I really want to understand the intrinsic details of the std::move() function.
The code for std::move() as stated here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html#Move_Semantics.
template <class T>
typename remove_reference<T>::type&&
move(T&& a)
{
return a;
}
Why does this code return a rvalue reference? The parameter is a type T rvalue reference. Does a
evaluate to the object pointed to by the rvalue reference, such that a rvalue reference is returned to the object? Also, why is the remove_reference<T>
part required?
The tutorial also writes
This move() gives its target the value of its argument, but is not obliged to preserve the value of its source. So, for a vector, move() could reasonably be expected to leave its argument as a zero-capacity vector to avoid having to copy all the elements. In other words, move is a potentially destructive read.
but then it is said that
The move function really does very little work. All move does is accept either an lvalue or rvalue argument, and return it as an rvalue without triggering a copy construction.
Should this be understood as, the std::move() could first "empty" the object (in this case a std::vector) and thereafter return the object as an rvalue (according to the C++ specification)? But, that the official std::move() does exactly as specified in the latter quote?
And why is it said that std::move() returns a rvalue, when it returns a rvalue reference?
The code for std::move() as stated here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html#Move_Semantics.
That was the proposed code in 2006. Before move semantics was part of C++. That's not how std::move
is implemented in C++, because the language changed significantly between 2006 and 2011. Look at a modern implementation if you want to understand std::move
, rather than understand some old proposal that describes something similar but different.
Why does this code return a rvalue reference?
Because that's the entire purpose of std::move
. Take an argument and cast it to an rvalue.
Asking why it does that is like asking why make_pair
returns a pair
.
The parameter is a type T rvalue reference.
Actually it's a "forwarding reference", which means it might be an lvalue reference or an rvalue reference.
Does
a
evaluate to the object pointed to by the rvalue reference, such that a rvalue reference is returned to the object?
Yes, that's how references work.
Also, why is the
remove_reference<T>
part required?
Because if std::move
is called with an lvalue then T
will be deduced to an lvalue reference type, such as int&
. To ensure the return type is int&&
you first need to remove the lvalue reference to get int
, then add &&
to get an rvalue reference, int&&
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With