Reputation: 24750
This answer writes a move constructor like this:
dumb_array(dumb_array&& other)
: dumb_array() // initialize via default constructor, C++11 only
{
swap(*this, other);
}
Note: this swap
is a custom swap also defined on the class, not std::swap
.
This answer suggests that use of std::move
:
you should only call std::move where appropriate, but this is were personal preferences come in.
I just watched a Scott Meyers talk on move semantics where he stated that an rvalue reference as a function parameter is turned back into an lvalue by virtue of the fact that it is now named, and therefore std::move is necessary once again turn it back into an rvalue.
In other words, the code above may very well not be doing a move operation, and that, unlike the quote above, use of std::move
in such contexts is not about personal preference but about actually gaining benefits of move semantics.
Is it accurate to say then that if std::move
is not explicitly used inside a move constructor or a move assignment operator, moving is probably not actually happening, and instead a copy is being done?
Upvotes: 3
Views: 544
Reputation: 27133
I just watched a Scott Meyers talk on move semantics where he stated that an rvalue reference as a function parameter is turned back into an lvalue by virtue of the fact that it is now named, and therefore std::move is necessary once again turn it back into an rvalue.
That's correct.
But there are many misconceptions around this topic.
In other words, the code above may very well not be doing a move operation
It won't do a move. However, it's likely that swap
is an efficient operation anyway and therefore you don't care.
use of std::move in such contexts is [...] about actually gaining benefits of move semantics.
Not true. Even if you use std::move
, there is no guarantee that any moving will occur.
Is it accurate to say then that if std::move is not explicitly used inside a move constructor or a move assignment operator, moving is probably not actually happening, and instead a copy is being done?
moving can occur, even if there is no std::move
.
So basically, std::move
is neither necessary, nor sufficient, for moving to occur. This may seem quite surprising.
I think there is really no shortcut to this. If you want to understand this, find a good comprehensive tutorial. E.g. The popular C++ Rvalue References Explained by Thomas Becker.
Upvotes: 1
Reputation: 171117
Is it accurate to say then that if
std::move
is not explicitly used inside a move constructor or a move assignment operator, moving is probably not actually happening, and instead a copy is being done?
No, that is most certainly not accurate. In the particular case in the question, it fully depends on the implementation of swap
.
A natural implementation would be swap(dumb_array&, dumb_array&)
which internally swaps some pointers, perhaps like this:
void swap(dumb_array &lhs, dumb_array &rhs)
{
std::swap(lhs.pointer_to_data, rhs.pointer_to_data);
}
If that is the case, then the move constructor you've shown certainly performs a lightweight move—just a pointer swap. Second, using std::move
when calling swap
would be downright wrong, as swap
takes lvalue references.
Upvotes: 4