Home > Software engineering >  Overload assignment operator and rule of zero
Overload assignment operator and rule of zero

Time:05-04

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.

CodePudding user response:

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).

  • Related