In what scenarios is it recommended to use std::move
?
std::vector<int> func()
{
std::vector<int> toReturn(1000000,5);
return std::move(toReturn); // 1
}
int main()
{
std::vector<int> datos = std::move(func()); // 2
// operaciones varias
}
In the example above, are the uses of std::move
? Why? What effects can misuse of std::move have?
What does it do
std::move
?std::move
converts aLvalue
to aRvalue
.What is it for
std::move
?C++11 adds a new constructor to the catalog. Your signature would be
POO(POO&&)
. This constructor, if it has been defined, is called automatically when a is receivedRvalue
and its function is to transfer the state of one object to another, avoiding making a copy of it.C++11 also allows you to use a new assignment operator, whose signature would be
POO& operator=(POO&&)
.These two new features can coexist without problems with the copy constructor and the assignment of all life. Just keep in mind that implementing the copy constructor disables the default constructor implementation
move
and vice versa. The above is also applicable to the assignment operator.This can be a significant performance improvement for heavy objects. An example:
Although it may seem obvious that copying a pointer from one place to another is much lighter than copying all the memory involved, it becomes clearer if you run the example. Running this code in release, on my machine it gives the following times:
It is also clear that the move syntax is only of interest if the object makes use (directly or indirectly) of dynamic memory, since this improvement is only applicable to pointers.
The downside of using
std::move
is that the original object loses its state. Normally this should not be a problem as the invocation of these semantics is not random.When should std::move be used?
The syntax
move
, as @Angel-Angel pointed out, can be executed automatically by callingreturn
. This is something that should be part of the optimization catalog of current compilers. The following two functions would be, in this case, equivalent.But then, if
std::move
it is usually invoked implicitly, when should you use it?Most often, this function is used primarily in constructor and assignment implementations
move
, as we ensure that nested objects benefit from this optimization:It is also necessary to use it when working with
std::unique_ptr
. Especially when they are in containers. If we want to extract or insert astd::unique_ptr
into a vector wildly, the program will not compile directly:What happens if the syntax is applied
move
to an object that doesn't have the constructor implementedmove
?What happens is that if the constructor is not found
move
, the compiler will try to call the constructor copy. If this is not found either then a compile time error will occur.In other words, applying the syntax
move
on an object that is not prepared for it should not have negative consequences in terms of both functionality and performance.Once all this has been explained and returning to the code of the initial question:
It is clear that the added value of the syntax in both cases is null, although it could be the case that the use
1
may be necessary in those rare cases in which the compiler does not apply optimizations in the return values.Very good explanation of Eferion, I wanted to comment on his explanation but I still can't; I would however like to add something to his explanation.
Since C++11, when the compiler encounters a
return
, it converts the return object to aRvalue;
so the move constructor is called, or the assignment operator, depending on the case.So you don't need to do
Source: http://cppactual.blogspot.com/2016/04/understanding-la-sintaxis-move.html