I have a simple struct Wrappe开发者_运维问答r
, distinguished by two templated assignment operator overloads:
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;
}
};
I then declare a and b:
Wrapper<float> a, b;
a = b;
assigning b
to a
will use the non-const templated assignment operator overload from above, and the number "2" is displayed.
What puzzles me is this: If I declare c
and d
,
Wrapper<float> c;
const Wrapper<float> d;
c = d;
and assign d
to c
, neither of the two assignment operator overloads is used, and no output is displayed; so the default copy assignment operator is invoked. Why does assigning d
to c
not use the const overloaded assignment operator provided? Or instead, why does assigning b
to a
not use the default copy assignment operator?
Why does assigning
d
toc
not use the const overloaded assignment operator provided?
The implicitly-declared copy assignment operator, which is declared as follows, is still generated:
Wrapper& operator=(const Wrapper&);
An operator template does not suppress generation of the implicitly-declared copy assignment operator. Since the argument (a const-qualified Wrapper
) is an exact match for the parameter of this operator (const Wrapper&
), it is selected during overload resolution.
The operator template is not selected and there is no ambiguity because--all other things being equal--a nontemplate is a better match during overload resolution than a template.
Why does assigning
b
toa
not use the default copy assignment operator?
The argument (a non-const-qualified Wrapper
) is a better match for the operator template that takes a Wrapper<U>&
than for the implicitly-declared copy assignment operator (which takes a const Wrapper<U>&
.
From the C++03 standard, §12.8/9:
A user-declared copy assignment operator
X::operator=
is a non-static non-template member function of classX
with exactly one parameter of typeX
,X&
,const X&
,volatile X&
orconst volatile X&
.
And §12.8/10:
If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly.
The fact that your operator=
is a template makes it not a copy assignment operator, so the class' implicit copy assignment operator is still generated by the compiler.
精彩评论