Why do you use std::move when you have && in C++11?

C++C++11Move Semantics

C++ Problem Overview


> Possible Duplicate:
> https://stackoverflow.com/q/3106110

I recently attended a C++11 seminar and the following tidbit of advice was given.

when you have && and you are unsure, you will almost always use std::move

Could any one explain to me why you should use std::move as opposed to some alternatives and some cases when you should not use std::move?

C++ Solutions


Solution 1 - C++

First, there's probably a misconception in the question I'll address:
Whenever you see T&& t in code (And T is an actual type, not a template type), keep in mind the value category of t is an lvalue(reference), not an rvalue(temporary) anymore. It's very confusing. The T&& merely means that t is constructed from an object that was an rvalue 1, but t itself is an lvalue, not an rvalue. If it has a name (in this case, t) then it's an lvalue and won't automatically move, but if it has no name (the result of 3+4) then it is an rvalue and will automatically move into it's result if it can. The type (in this case T&&) has almost nothing to do with the value category of the variable (in this case, an lvalue).

That being said, if you have T&& t written in your code, that means you have a reference to a variable that was a temporary, and it is ok to destroy if you want to. If you need to access the variable multiple times, you do not want to std::move from it, or else it would lose it's value. But the last time you acccess t it is safe to std::move it's value to another T if you wish. (And 95% of the time, that's what you want to do). All of this also applies to auto&& variables.

1. if T is a template type, T&& is a forwarding reference instead, in which case you use std::forward<T>(t) instead of std::move(t) the last time. See this question.

Solution 2 - C++

I found this article to be pretty enlightening on the subject of rvalue references in general. He mentions std::move towards the end. This is probably the most relevant quote:

> We need to use std::move, from <utility> -- std::move is a way of > saying, "ok, honest to God I know I have an lvalue, but I want it to > be an rvalue." std::move does not, in and of itself, move anything; it > just turns an lvalue into an rvalue, so that you can invoke the move > constructor.


Say you have a move constructor that looks like this:

MyClass::MyClass(MyClass&& other): myMember(other.myMember)
{
    // Whatever else.
}

When you use the statement other.myMember, the value that's returned is an lvalue. Thus the code uses the copy constructor to initialize this->myMember. But since this is a move constructor, we know that other is a temporary object, and therefore so are its members. So we really want to use the more-efficient move constructor to initialize this->myMember. Using std::move makes sure that the compiler treats other.myMember like an rvalue reference and calls the move constructor, as you'd want it to:

MyClass::MyClass(MyClass&& other): myMember(std::move(other.myMember))
{
    // Whatever else.
}

Just don't use std::move on objects you need to keep around - move constructors are pretty much guaranteed to muck up any objects passed into them. That's why they're only used with temporaries.

Hope that helps!

Solution 3 - C++

When you have an object of type T&&, a rvalue, it means that this object is safe to be moved, as no one else will depend on its internal state later.

As moving should never be more expensive than copying, you will almost always want to move it. And to move it, you have to use the std::move function.

When should you avoid std::move, even if it would be safe? I wouldn't use it in trivial examples, e.g.,:

 int x = 0;
 int y = std::move(x);

Beside that, I see no downsides. If it does not complicate the code, moving should be done whenever possible IMHO.

Another example, where you don't want to move are return values. The language guarantees that return values are (at least) moved, so you should not write

return std::move(x); // not recommended

(If you are lucky, return value optimization hits, which is even better than a move operation.)

Solution 4 - C++

You can use move when you need to "transfer" the content of an object somewhere else, without doing a copy. It's also possible for an object to take the content of a temporary object without doing a copy, with std::move.

Read more on Rvalue references and move constructors from wikipedia.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionpyCthonView Question on Stackoverflow
Solution 1 - C++Mooing DuckView Answer on Stackoverflow
Solution 2 - C++Xavier HoltView Answer on Stackoverflow
Solution 3 - C++Philipp ClaßenView Answer on Stackoverflow
Solution 4 - C++Rahul TripathiView Answer on Stackoverflow