The standard library move function is a good example of a template that uses rvalue references. The standard library defines std::move as follows:
Template <typename t>typename remove_reference<T>::type&& Move (t&& T) { return static_cast<typename remove_reference<t>::type&&>(T);}
We consider the following code work process:
std::string S1 ("hi"= Std::move (string("hi ")); // correct, move data from a right value s2 = std::move (S1); // correct, but after the assignment, the value of the S1 is indeterminate.
In the first assignment, the argument is the right value of type string, so the procedure is:
- Inferred T is of type string
- The type member of the remove_reference<string> is a string
- The move return type is string&&
- The type of the function parameter T of move is string&&
Thus, this invocation instantiates Move<string>, which is the function
string&& Move (string &&t)
In the second assignment, the argument is an lvalue, so:
- Infer that the type of T is string&
- The type member of the remove_reference<string&> is a string
- The move return type is string&&
- The type of the function parameter T of move is string& &&, which is folded into string&
Thus, this invocation instantiates move<string&>
string&& Move (string &t)
Typically, static_cast can only be used for other legitimate type conversions. But there is a concession rule for rvalue: although it is not possible to implicitly convert an lvalue to an rvalue reference, we can convert an lvalue to an rvalue using the static_cast display.
C + + Primer notes--Understanding Std::move