dimanche 27 mai 2018

overload resolution of templated special member (operator=)

Context: In an attempt to implement the copy and swap idiom on a templated homemade shared_ptr. I'm having trouble to get this function called:

    template<typename U>
    shared_ptr<T>& operator=(shared_ptr<U> rhs)
    {
        static_assert(std::is_base_of<T, U>::value);
        swap(*this, rhs);
        return *this;
    }

Code stripped from the unecessary:

The following code does not compile. The "x=y" line is an attempt to use:

    foo<T>& operator=(const foo<U>& ptr) = delete;

If I remove/comment the deleted functions line. Meaning if I do not define them, the compiler will do it for me and the code will compile. However,the special member generated by the compiler will be preferred to my operator which will not be called.

template<typename T> 
class foo
{
public:

    // copy&swap
    template<typename U>
    foo<T>& operator=(foo<U> rhs)
    {
        // whatever is needed swap and all
        return *this;
    }

    template<typename U>
    foo<T>& operator=(const foo<U>& ptr) = delete;
    template<typename U>
    foo<T>& operator=(foo<U>&& ptr) = delete;

    foo<T>& operator=(foo<T>&& ptr) = delete;
};

int main()
{
    foo<int> x,y;
    x = y;
    return 0;
}

Questions:

  • The overload resolution is not clear to me here. Why is one signature preferred to the other?
  • If the function is deleted, I understand it is not a "substitution failure", but still it is a failure at signature level, not inside the body, why does the compiler stop looking for a match?
  • Any solution to get the function to be called ?

Aucun commentaire:

Enregistrer un commentaire