Peter Silon Peter Silon - 9 months ago 65
C++ Question

rvalues with copy operator

Consider this simple class

class Foo
Foo() = default;
Foo(const Foo &) = default;
Foo & operator=(const Foo & rhs)
return *this;
Foo & operator=(Foo && rhs) = delete;

Foo getFoo()
Foo f;
return f;

int main()
Foo f;
Foo & rf = f;
rf = getFoo(); // Use of deleted move assignment.
return 0;

When I compile the example above I get
error: use of deleted function 'Foo& Foo::operator=(Foo&&)'

From the Copy Assignment:

If only the copy assignment is provided, all argument categories select it (as long as it takes its argument by value or as reference to const, since rvalues can bind to const references), which makes copy assignment the fallback for move assignment, when move is unavailable.

Why doesn't the compiler fallback to copy assignment when const lvalue reference can bind to rvalue and
const Foo & f = getFoo();

Compiler - gcc 4.7.2.


There is no fallback, the concept is called overload resolution.

The compiler performs the overload resolution and makes the decision before it checks whether the method is deleted or not. The compiler decides that the move constructor is the best choice, then it determines that this method has been deleted, hence the error.

Note 1: delete does not literally delete the method. If delete is used, the method is defined as deleted, but it still can be found by the overload resolution.

From the documentation (emphasis mine):

... overload resolution takes place first, and the program is only ill-formed if the deleted function was selected.

In your example, the move constructor is available (from the overload resolution point of view). However, it is defined as deleted.

Note 2: If you don't want your class to have a move constructor, simply do not define it. The compiler will not generate a move constructor if you have declared one of the following: copy constructor, copy assignment operator, move assignment operator, destructor.