In C++ Templates The Complete Guide in section 5.3 Member Templates it's written:
Note that a template assignment operator doesn't replace the default assignment operator. For assignments of stacks of the same type, the default assignment operator is still called.
Is this correct, because when I ran below code:
#include<iostream>
using namespace std;
template<typename T>
class Pair
{
public:
T pair1,pair2;
Pair(T i,T j):pair1(i),pair2(j){}
template<typename T1>Pair<T>& operator=(Pair<T1>&);
};
template<typename T>
template<typename T1>
Pair<T>& Pair<T>::operator=(Pair<T1>& temp)
{
this->pair1 =temp.pair1*10;//At this point
this->pair2=temp.pair2;
return *this;
}
int main()
{
Pair<int>P1(10,20);
Pair<int>P2(1,2);
P2=P1;
cout<<P2.pair1<<' '<<P2.pair2<<endl;
return 1;
}
I got answer 100 20.
It didn't give the default assignment answer.
Is that a typing mistake in C++ Templates the Complete Guide ?
C++ Templates: The Complete Guide By David Vandevoorde, Nicolai M. Josuttis
Publisher : Addison Wesley
Pub Date : November 12, 2002 ISBN : 0-201-73484-2 Pages : 552
The copy assignment operator is indeed implicitly declared and considered by overload resolution.
A user-declared copy assignment operator
X::operator=
is a non-static non-template member function of classX
[..].
If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly . [..] The implicitly-declared copy assignment operator for a classX
will have the formX& X::operator=(const X&)
if
- each direct base class
B
ofX
has a copy assignment operator whose parameter is of typeconst B&
,const volatile B&
orB
, and- for all the non-static data members of
X
that are of a class typeM
(or array thereof), each such class type has a copy assignment operator whose parameter is of typeconst M&
,const volatile M&
orM
.Otherwise, [..]
As you can see the implicitly-declared copy assignment operator for Pair<int>
has one parameter of type Pair<int> const&
- note the const
in particular! Overload resolution favours non- const
references over const
ones if both can be bound to the argument, [over.ics.rank]/3:
Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of the following rules applies:
— Standard conversion sequence
S1
is a better conversion sequence than standard conversion sequenceS2
if
- [..]
S1
andS2
are reference bindings (8.5.3), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized byS2
refers is more cv-qualified than the type to which the reference initialized byS1
refers.
The specialization of the template lacks a const
in the reference parameter, thus it's a better match and is selected.
The default assignment operator accepts the argument as a const reference: http://en.cppreference.com/w/cpp/language/as_operator .
You have defined a version without const
, and your version is better in the context of overload resolution (no conversion required).
Try with the following change :
int main()
{
Pair<int>P1(10,20);
Pair<int>P2(1,2);
const Pair<int>& x = P1;
P2=x;
cout<<P2.pair1<<' '<<P2.pair2<<endl;
return 1;
}
to see the expected result.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.