I think to recall that someone told me that these two methods
foo(std::vector<int>&& v) {
member = std::move(v);
}
bar(std::vector<int> v) {
member = std::move(v);
}
both will not invoke a copy if there is a move at the call site
foo(std::move(v1));
bar(std::move(v2));
since the compiler will optimize the call and treat the bar
case as if it would take the argument by rvalue reference and therefore one should favor the bar
syntax since it's less convoluted and can also be called with an lvalue (in which case of course a copy will be made).
Is this true? can one rely on the bar
case not creating a copy so long as one calls it with an rvalue?
can one rely on the barcase not creating a copy so long as one calls it with an rvalue?
No, not necessarily. An example in which a copy will take place:
const std::vector<int> vec;
bar( std::move(vec) );
Here std::move
will cast vec
(an lvalue ) to an xvalue (ie rvalue ). But it won't be moved since vec
is constant and can not be modified. Thus the move constructor of std::vector
won't be called.
Now I tried your code in godbolt and I noticed something that might disappoint you a bit.
This code:
#include <vector>
#include <utility>
void foo( std::vector<int>&& v )
{
auto member = std::move(v);
}
void bar( std::vector<int> v )
{
auto member = std::move(v);
}
int main( )
{
std::vector<int> v1;
std::vector<int> v2;
foo( std::move(v1) ); // this one oviously moves.
bar( std::move(v2) ); // this one does not move, it copies!
}
Here is what I saw:
For foo( std::move(v1) );
:
mov rdi, rsp
.
.
.
call foo(std::vector<int, std::allocator<int> >&&)
Yes, you see the &&
. It's a move .
For bar( std::move(v2) );
:
lea rdi, [rsp+32]
.
.
.
call bar(std::vector<int, std::allocator<int> >)
I don't see any &&
so I guess it's a copy .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.