What is std::move(), and when should it be used?

What is std::move(), and when should it be used?

std::move implementation
return std::move
std::move vector
std::move unique_ptr
std::move shared_ptr
when not to use std::move
std::move rvalue
c move constructor
  1. What is it?
  2. What does it do?
  3. When should it be used?

Good links are appreciated.


Wikipedia Page on C++11 R-value references and move constructors

  1. In C++11, in addition to copy constructors, objects can have move constructors. (And in addition to copy assignment operators, they have move assignment operators.)
  2. The move constructor is used instead of the copy constructor, if the object has type "rvalue-reference" (Type &&).
  3. std::move() is a cast that produces an rvalue-reference to an object, to enable moving from it.

It's a new C++ way to avoid copies. For example, using a move constructor, a std::vector could just copy its internal pointer to data to the new object, leaving the moved object in an incorrect state, avoiding to copy all data. This would be C++-valid.

Try googling for move semantics, rvalue, perfect forwarding.

What is std::move(), and when should it be used?, std::move() is a cast that produces an rvalue-reference to an object, to enable moving from it. It's a new C++ way to avoid copies. For example, using a move  -1 "std::move() is the C++11 way to use move semantics" Please fix that. std::move() is not the way to use move semantics, move semantics are performed transparently to the programmer. move its only a cast to pass a value from one point to another where the original lvalue will no longer be used.


1. "What is it?"

While std::move() is technically a function - I would say it isn't really a function. It's sort of a converter between ways the compiler considers an expression's value.

2. "What does it do?"

The first thing to note is that std::move() doesn't actually move anything. It converts an expression from being an lvalue (such as a named variable) to being an xvalue. An xvalue tells the compiler:

You can plunder me, move anything I'm holding and use it elsewhere (since I'm going to be destroyed soon anyway)".

in other words, when you use std::move(x), you're allowing the compiler to cannibalize x. Thus if x has, say, its own buffer in memory - after std::move()ing the compiler can have another object own it instead.

You can also move from a prvalue (such as a temporary you're passing around), but this is rarely useful.

3. "When should it be used?"

Another way to ask this question is "What would I cannibalize an existing object's resources for?" well, if you're writing application code, you would probably not be messing around a lot with temporary objects created by the compiler. So mainly you would do this in places like constructors, operator methods, standard-library-algorithm-like functions etc. where objects get created and destroyed automagically a lot. Of course, that's just a rule of thumb.

A typical use is 'moving' resources from one object to another instead of copying. @Guillaume links to this page which has a straightforward short example: swapping two objects with less copying.

template <class T>
swap(T& a, T& b) {
    T tmp(a);   // we now have two copies of a
    a = b;      // we now have two copies of b (+ discarded a copy of a)
    b = tmp;    // we now have two copies of tmp (+ discarded a copy of b)
}

using move allows you to swap the resources instead of copying them around:

template <class T>
swap(T& a, T& b) {
    T tmp(std::move(a));
    a = std::move(b);   
    b = std::move(tmp);
}

Think of what happens when T is, say, vector<int> of size n. In the first version you read and write 3*n elements, in the second version you basically read and write just the 3 pointers to the vectors' buffers, plus the 3 buffers' sizes. Of course, class T needs to know how to do the moving; your class should have a move-assignment operator and a move-constructor for class T for this to work.

Understanding when not to std::move in C++, However, std::move must be used judiciously; using it blithely may lead to struct U { }; struct T { operator U(); }; U f() { T t; return std::move (t); }. While in general std::move is a great addition to the language, it’s not always appropriate to use it, and, sadly, the rules are fairly complicated. Fortunately, the compiler is able to recognize the contexts where a call to std::move would either prevent elision of a move or a copy—or would actually not make a difference—and warns appropriately.


You can use move when you need to "transfer" the content of an object somewhere else, without doing a copy (i.e. the content is not duplicated, that's why it could be used on some non-copyable objects, like a unique_ptr). It's also possible for an object to take the content of a temporary object without doing a copy (and save a lot of time), with std::move.

This link really helped me out :

http://thbecker.net/articles/rvalue_references/section_01.html

I'm sorry if my answer is coming too late, but I was also looking for a good link for the std::move, and I found the links above a little bit "austere".

This puts the emphasis on r-value reference, in which context you should use them, and I think it's more detailed, that's why I wanted to share this link here.

15.4, In the first case, we passed push_back() an l-value, so it used copy Consequently, you should not use std::move() on any persistent object  std::move. In C++11, std::move is a standard library function that serves a single purpose -- to convert its argument into an r-value. We can pass an l-value to std::move, and it will return an r-value reference. std::move is defined in the utility header.


When should I use std::move in C++11?, Std::unique_ptr<Foo> p (new Foo()); vector.push_back(p); This statement will give compilation error. The reason is: Rule of unique ownership will be applied. std::move() is a cast that produces an rvalue-reference to an object, to enable moving from it. It’s a new C++ way to avoid copies. For example, using a move constructor, an std::vector could copy its internal pointer to data to the new object, leaving the moving object in an incorrect state, avoiding to copy all data.


std::move itself doesn't really do much. I thought that it called the moved constructor for an object, but it really just performs a type cast (casting an lvalue variable to an rvalue so that the said variable can be passed as an argument to a move constructor or assignment operator).

So std::move is just used as a precursor to using move semantics. Move semantics is essentially an efficient way for dealing with temporary objects.

Consider Object A = B + C + D + E + F;

This is nice looking code, but E + F produces a temporary object. Then D + temp produces another temporary object and so on. In each normal "+" operator of a class, deep copies occur.

For example

Object Object::operator+ (const Object& rhs) {
    Object temp (*this);
    // logic for adding
    return temp;
}

The creation of the temporary object in this function is useless - these temporary objects will be deleted at the end of the line anyway as they go out of scope.

We can rather use move semantics to "plunder" the temporary objects and do something like

 Object& Object::operator+ (Object&& rhs) {
     // logic to modify rhs directly
     return rhs;
 }

This avoid needless deep copies being made. With reference to the example, the only part where deep copying occurs is now E + F. The rest uses move semantics. The move constructor or assignment operator also needs to be implemented to assign the result to A.

Quick Q: What's the difference between std::move and std::forward , Quick A: One is used to forward parameters, one to move an object. When you see std::move, it indicates that the value of the object should not be used int main() {; std::cout << "initial caller passes rvalue:\n";; forwarding( 5 );  One should use std::move to acquire an rvalue reference of an object, that's it. Many people have a misconception that std::move actually performs moving of the object. In fact, std::move doesn't generate any executable code at all. To give you more details, std::move performs an unconditional cast


std::move - move, of the moved-from object should only be destroyed or assigned a new value; Header <algorithm> overloads this function, providing a similar behavior applied to move example #include <utility> // std::move #include <iostream> // std::cout std::string int main () { std::string foo = "foo-string" ; std::string bar = "bar-string"  I just found myself not fully understanding the logic of std::move(). At first, I googled it but seems like there are only documents about how to use std::move(), not how its structure works. I mean, I know what the template member function is but when I look into std::move() definition in VS2010, it is still confusing.


std::move in C++, The range used is [first,last], which contains all the elements between first and last, including std :: move (vec1.begin(), vec1.begin() + 4, vec2.begin() + 1); If you like GeeksforGeeks and would like to contribute, you can also write an article​  One cannot use std::move in this scenario, so it's not less efficient, it's simply wrong. In scenarios where one can use both move semantics and emplace_back, one should normally use both. – n. 'pronouns' m. Jan 27 '19 at 17:39


Note quite the standard, but [1] says under the "Notes" section , on: Catching use-after-move C++ bugs with Clang's cons. such as the assignment operator, can be safely used on the object after it was moved from. Defining a move constructor and move assignment work analogously to their copy counterparts. However, whereas the copy flavors of these functions take a const l-value reference parameter, the move flavors of these functions use non-const r-value reference parameters. Here’s the same Auto_ptr3 class as above,