In C++11, methods can be overloaded on whether or not the expression that denotes the object on which the method is called is an lvalue or an rvalue. If I return *this
The type of *this
is always an lvalue:
§9.3.2 [class.this] p1
In the body of a non-static (9.3) member function, the keyword
this
is a prvalue expression whose value is the address of the object for which the function is called. The type ofthis
in a member function of a classX
isX*
. [...]
§5.3.1 [expr.unary.op] p1
The unary
*
operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.
So you will need to std::move
if you want to invoke the move constructor.
The following code snippet shows that:
#include <iostream>
#include <utility>
struct test{
test(){}
test(test const&){ std::cout << "copy ctor // #1\n"; }
test(test&&){ std::cout << "move ctor // #2\n"; }
test f_no_move() &&{ return *this; }
test f_move() &&{ return std::move(*this); }
};
int main(){
test().f_no_move(); // #1
test().f_move(); // #2
}
Using Clang 3.1 (the only compiler I know that implements ref-qualifiers), I get the following output:
$ clang++ -std=c++0x -stdlib=libc++ -pedantic -Wall t.cpp
$ ./a.out
copy ctor // #1
move ctor // #2