Andreas Lykke Iversen
Andreas Lykke Iversen

Reputation: 141

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?

Upvotes: 4

Views: 3419

Answers (3)

Jonathan Wakely
Jonathan Wakely

Reputation: 171273

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

Upvotes: 10

SergeyA
SergeyA

Reputation: 62573

std::move can be thought of as a glorified cast. All it does it converts the type of it's argument (an object or a result of an expression) into so-called xvalue. It does so by returning an rvalue reference to it.

It also takes care of the fact that deduced type of the argument might be an lvalue, in which cast T becomes really an lvalue reference - this is why it has to remove reference from T to get the 'real' type of the argument.

That's it. It doesn't actually move anything, clean up objects or any of the sorts. The actual object modification is done by corresponding move constructor or assingment operator.

Upvotes: 1

Pete Becker
Pete Becker

Reputation: 76295

void f(const my_type&);
void f(my_type&&);
my_type m;
f(m);           // calls f(const my_type&)
f(std::move(m); // calls f(my_type&&)

The only thing that the call to std::move does is ensure that the type of the argument to f is an rvalue reference. It's up to f what to do with that reference once it has it.

You could do the same thing with a cast:

f(my_type&&(m));

but calling std::move is clearer and more consistent when used in more than one place.

Upvotes: 0

Related Questions