Reputation: 11536
If I define a copy assignment operator that invokes the copy constructor using pass by value for class thing
:
thing& operator= (thing x) {
and a move assignment operator for the same class:
thing& operator= (thing&& x) {
Trying to invoke the move assignment results in an error from gcc:
error: ambiguous overload for ‘operator=’ (operand types are ‘thing’ and ‘std::remove_reference<thing&>::type {aka thing}’)
However, if the copy assign instead uses pass by reference:
thing& operator= (thing& x) {
Compilation is fine, and both operators can be invoked. Why is this?
Complete C++11 test code:
#include <iostream>
#include <utility>
using namespace std;
class thing {
public:
thing () { }
thing (thing& x) {
cout << "Copy constructor.\n";
}
thing (thing&& x) {
cout << "Move constructor.\n";
}
thing& operator= (thing x) {
cout << "Copy assign using pass by value.\n";
return *this;
}
thing& operator= (thing&& x) {
cout << "Move assign.\n";
return *this;
}
};
int main (void) {
thing a, b;
// Invoke move assignment:
a = move(b);
return 0;
}
Upvotes: 13
Views: 2222
Reputation: 42889
Calling move(b)
returns an rvalue
.
Both operator=(thing &&x)
and operator=(thing x)
can accept rvalues
as input.
As such, the two overloads are ambiguous and the compiler rightfully complains because it can't choose between them.
Upvotes: 5