Assigning an operator template overloads mystery

I have a simple Wrapper structure, featuring two overloaded assignment pattern operations:

 template<typename T> struct Wrapper { Wrapper() {} template <typename U> Wrapper &operator=(const Wrapper<U> &rhs) { cout << "1" << endl; return *this; } template <typename U> Wrapper &operator=(Wrapper<U> &rhs) { cout << "2" << endl; return *this; } }; 

Then I declare a and b:

 Wrapper<float> a, b; a = b; 

assignment b to a will use the overload of the non-constant template assignment operator on top and the number "2" will be displayed.

What puzzles me: if I declare c and d ,

 Wrapper<float> c; const Wrapper<float> d; c = d; 

and assign d c , none of the two overloads of the destination operator is used, and the output is not output; therefore, the default copy destination statement is called. Why is the overloaded assignment operator const not used when assigning d to c ? Or instead, why assigning b to a does not use the default copy operator?

+7
source share
2 answers

Why doesn't the d to c assignment use the overloaded assignment operator const?

An implicitly declared copy destination statement, which is declared as follows, is still generated:

 Wrapper& operator=(const Wrapper&); 

An operator pattern does not suppress the generation of an implicitly declared copy assignment operator. Since the argument (const-qual Wrapper ) is an exact match for the parameter of this operator ( const Wrapper& ), it is selected when overload resolution is enabled.

An operator template is not selected, and there is no ambiguity, because - ceteris paribus - the absence of a template is a better match during overload resolution than the template.

Why is the default copy operator not used when assigning b to a ?

The argument (non-constant qualified Wrapper ) is a better match for the operator template that accepts Wrapper<U>& than for the implicitly declared copy destination operator (which accepts const Wrapper<U>& .

+18
source

From the C ++ 03 standard, ยง12.8 / 9:

The user copy assignment operator X::operator= is a non - static non-template function of a member of class X with exactly one parameter of type X , X& , const X& , volatile X& or const volatile X& .

And ยง12.8 / 10:

If the class definition does not explicitly declare the copy assignment operator, it is declared implicitly.

The fact that your operator= is a template makes it not a copy assignment operator, so the implicit copy operator of an instance is still generated by the compiler.

+6
source

All Articles