Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding the code for std::move()

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?

like image 734
Andreas Lykke Iversen Avatar asked Dec 19 '22 18:12

Andreas Lykke Iversen


1 Answers

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&&.

like image 62
Jonathan Wakely Avatar answered Dec 24 '22 01:12

Jonathan Wakely