move
the object is there any dependence between new and old ones?int main () { int a = 100; std::cout<<&a<<std::endl; auto a_copy = a; // deduced as int std::cout<<&a_copy<<std::endl; auto a_move = std::move(a); // deduced as int std::cout<<&a_move<<std::endl; };
output:
0x7fffffffe094 0x7fffffffe098 0x7fffffffe09c
std::string: The std::string on Linux behaves strangely. On one hand, copying is very fast; on the other hand, moving is only 16 times faster than copying. The becomes even more strange if I compile and execute the program without optimization.
It's faster because moving allows the source to be left in a invalid state, so you can steal it's resources. For example, if a object holds a pointer to a large block of allocated memory, a move can simply steal the pointer while a copy must allocate its own memory and copy the whole memory block.
std::move is actually just a request to move and if the type of the object has not a move constructor/assign-operator defined or generated the move operation will fall back to a copy.
std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.
In this example, there is no difference. We will end up with 3 int
s with value 100. There could definitely be a difference with different types though. For instance, let's consider something like vector<int>
:
std::vector<int> a = {1, 2, 3, 4, 5}; // a has size 5 auto a_copy = a; // copy a. now we have two vectors of size 5 auto a_move = std::move(a); // *move* a into a_move
The last variable, a_move
, takes ownership of a
's internal pointers. So what we end up with is a_move
is a vector of size 5, but a
is now empty. The move
is much more efficient than a copy
(imagine if it was a vector of 1000 strings instead - a_copy
would involve allocating a 1000-string buffer and copying 1000 strings, but a_move
just assigns a couple pointers).
For some other types, one might be invalid:
std::unique_ptr<int> a{new int 42}; auto a_copy = a; // error auto a_move = std::move(a); // OK, now a_move owns 42, but a points to nothing
For many types, there's no difference though:
std::array<int, 100> a; auto a_copy = a; // copy 100 ints auto a_move = std::move(a); // also copy 100 ints, no special move ctor
More generally:
T a; auto a_copy = a; // calls T(const T& ), the copy constructor auto a_move = std::move(a); // calls T(T&& ), the move constructor
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With