Search code examples
c++operatorsoverloading

Overload assignment operator and rule of zero


I have written a template class A<T> and I am making use of the rule of zero (I let the compiler generate the destructor, copy/move constructors and assignment operator overloadings). However, I need now a customized assignment operator that takes a different type B<T> as argument:

A<T>& operator=(const B<T>& rhs);

Will this implementation prevent the compiler from generating the default destructor etc.? My guess is no, because the compiler generates

A<T>& operator=(const A<T>& rhs);

which is just entirely different from the overloading I want to implement.


Solution

  • According to my understanding, adding a operator= overload will not prevent the compiler from generating the default one according to the rule of 0.

    I base this understanding on the fact that your operator= overload is not in fact a copy assignment, nor a move assignment.
    Therefore the rules about generaing default constructors and assignment operators are not relevant.

    I verified it with MSVC.

    You can use the code below to verify with your compiler:

    #include <iostream>
    
    template <typename T>
    struct B
    {
        B(T const & n) : bn(n) {}
        T bn{ 0 };
    };
    
    template <typename T>
    struct A
    {
        A(T const & n) : an(n) {}
        A<T>& operator=(const B<T>& rhs)
        {
            an = rhs.bn;
            return *this;
        }
        T an{ 0 };
    };
    
    int main()
    {
        A<int> a1{ 5 };
        A<int> a2{ 6 };
        std::cout << a2.an << ",";
        a2 = a1;    // Use default assinment
        std::cout << a2.an << ",";
        B<int> b{ 3 };
        a2 = b;     // Use custom assignment
        std::cout << a2.an << std::endl;
        return 0;
    }
    

    The output should be: 6,5,3:

    6 is the value A<int> a2 is constructed with, 5 is the value assigned from A<int> a1, and 3 is the value assigned from B<int> b.

    Note: an alternative would be to use a user-defined conversion function, as @LouisGo commented (see above).