Well, I am very interested in learning about this apparently useful new feature, but it is difficult for me because all the quality information available is in English. In the same way I try to learn but my English is not so good that I can only understand a few things. That is why I am asking here if someone could explain what the semantics of movement are and the details that go with it.
The problem.
Movement semantics are a tool that comes to the aid of the C++ programmer to solve a performance problem that has been dragging on since the creation of the language, let's see an example of inefficient code:
TO_UPPER
When you call copy the variableQuijote
to the local variable of the functionin
, this copy is processed and then the processed copy is returned and it is copied again .Before move semantics in C++ we could use references to solve the above problem:
Using references avoids making unnecessary copies of variables and improves code performance. But references don't solve all problems:
In the above code we have a dangling reference since
result
the function's internal variableread_table
ceases to exist the moment the function is exited and therefore using it outside the function will cause errors... so we return to the handy references :The solution.
Imagine that instead of copying data from one function to another we could move this data, that's the semantics of movement.
The semantics of movement are supported by " Reference to Right Value " (RvD), which allow referencing temporary values, which was impossible before C++11.
Right Value References use the declarator
&&
(in declaration context it corresponds to " Right Value Reference " in expression it is the logical AND operator ).But what is an RvD ?, a Right Value is everything that has the capacity to be to the right of an expression and generally a temporary value, all the following expressions to the right of it
=
are temporary Right Values:Before C++11 you couldn't reference Right Values, but by adding the move semantics these values are referable and functions can be overloaded to accept them:
For objects that handle resources, when they receive a temporary value (a value that we know is going to be removed after evaluating the expression) we can decide to swap the resource from the temporary to avoid more expensive operations:
Free motion semantics!
The standard library adapts all of its constructs from C++11 to take advantage of move semantics, so by switching to a C++11 or higher compiler we get these semantics without changing the code. This usually implies a performance improvement just by recompiling!
So now we can fix the problems we had before:
Since the
std::string
C++11 template incorporates move semantics, when we call the functionTO_UPPER
with temporary values, the values will be moved saving unnecessary copies. The functionstd::move
transforms a value to RvD, so going back to the overloaded function example:It is important to note that
std::move
, despite receiving the name move , it does not move anything, it only transforms a variable to RvD, so this instruction does not move anything anywhere:What happens to what I move?
As we have seen, it
std::move
transforms from reference (&
) to RvD (&&
) and it is actually the instruction or constructor that receives said RvD that performs the movement operation, but what about the moved objects?According to the C++ standard , moved objects are valid even though their content is indeterminate (translation and emphasis mine):
Not all that glitters is gold.
As almost every time a new feature is added, incorrect uses of it arise, it is not convenient to abuse
std::move
it since it can lead to a worsening of performance by preventing the compiler from applying optimizations, for example the following code has a problem:According to the C++ standard (translation and highlighting mine):
So it's a good idea not to abuse calls
std::move
as they avoid these compiler optimizations known as "Return Value Optimization" (OvR) ( RVO in English ). It is worth noting that OvR exists in C++ before C++11 and does not require any action on the part of the programmer to take advantage of it.More information.
You can see this explanation of the semantics of movement in this video (video in Spanish, text in English).