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