There are a number of situations that either make you specific manipulations to avoid copying data or allow these copies to be made creating a cost of performance.
This typically occurs in types where you want value type semantics (see more on this topic this > and this answer, it's another language but the idea is the same) that are usually stored in stack or as an integral part of another object in the heap . In other words, you work effectively with the value of the data and not with a reference to the actual value. But to avoid the cost of copying these values some types are accessed by reference - through a pointer - while maintaining their value semantics. String is a very typical case.
It's true that some types can be optimized by the compiler and this happens with string , for example. But the compiler does not know of all types. It was necessary to allow each type to be defined in such a way that optimization was always done.
With std::move
you can move one value to another reference. This is done through a pointer, it is very cheap.
Someone may be wondering, why do you need to move? Why not copy as always in C ++? The problem with copying is that it retains property of the object (of the value).
When you have value semantics, you never have two or more references to an object (a value) because it is self referenced, the value exists by itself. When you copy the value, the copy is another object and has another owner (a variable, for example). Although initially the values are the same, they happen to be two completely different and independent objects.
You want to ensure that these types that have reference but use value semantics also do not have more than one owner. A simple copy would create a new reference for the object. This has implications in concurrent execution environments and would complicate the automatic management of memory because it would have to control how many references the object has and only when it has zero is that the object should be destroyed.
As the possibility of moving, we are telling the compiler that the object can only have one owner, who does not have as two owners trying to access the object simultaneously and does not need control how many owner has . This greatly simplifies everything that has to be done in your code and what the compiler has to generate to control the lifetime of the object.
You've always been able to do this, but now it has a standardized form and the compiler can benefit since it is standard. He can make decisions based on this.
In practice this std:move
disappears from the code after compiling. It even serves to inform how the compiler should deal with it.
This made it possible to create std:unique_ptr
which greatly simplified automatic memory management without involving overhead processing or memory. And this is a revolution for C ++.
The implementation of it is very simple, it's something like this:
template <class T>
typename remove_reference<T>::type&&
move(T&& a) {
return a;
}
Example usage:
template <class T> swap(T& a, T& b) {
T tmp(a); //a passa ter duas referências p/ "a", a original que passou o parâmetro e aqui
a = b;//e agora duas cópias para "b"
b = tmp; //mais um cópia para "tmp" que já é cópia para "a"
}
See the difference:
template <class T> swap(T& a, T& b) {
T tmp(std::move(a)); //nenhuma cópia é feita em nenhum do casos, só ponteiros se movimentam
a = std::move(b);
b = std::move(tmp);
}
When you use std:move
, the variable is giving up the object's property. That can be given back by the new owner.
Surely there is more to talk about. And everything I said is a simplification.
Wikipedia Reference .
Pre-official documentation .