I am reading about the std::move
, move constructor and move assignment operator.
To be honest, all I got now is confusion. Now I have a class:
class A{
public:
int key;
int value;
A(){key = 3; value = 4;}
//Simple move constructor
A(A&& B){ A.key = std::move(B.key);
A.value = std::move(B.value);}
};
B
is an rvalue reference, why you can apply std::move
to an ravlue reference's member?B.key
and B.value
have been moved, both have been invalidated, but how B
as an object of class A
gets invalidated?A a(A())
, A()
is apparently an rvlaue, can A()
be moved by std::move
and why?Similarly, if I have a function
int add(int && z){
int x = std:move(z);
int y = std:move(z);
return x+y;
}
What if I call add(5)
, how can 5
be moved and why?
And notice that z
has been moved twice, after z
has been moved first time, it has been invalidated, how can you move it again?
foo (T && Z )
(T
, Z
can be anything), in the body of the definition Why on earth I should use std::move(Z)
since Z
is already passed by an rvalue reference and when should I use std::move
? std::move
does not move anything, but "marks" its argument to be a rvalue reference. Technically, it converts the type to a rvalue reference. Then, the rvalue reference it's being moved by the corresponding move constructor or move assignment operator. For objects that contain only members with trivial move ctors/assignment operators, the move ctor/assignment operator is trivial and simply copies. In general, the move ctor/assignment operator of the object calls the move ctor/assignment operator of all its members.
So, whenever you write
int x = 10; int y = std::move(x);
on the right hand side of the assignment y = std::move(x)
, you have a rvalue reference of type int&&
. However, int
does not have a non-trivial move ctor, and the rvalue is simply copied into y
, nothing is changed in x
.
On the other hand,
string s = "some string"; string moved_s = std::move(s); // here we tell the compiler that we can "steal" the resource of s
is different. The move constructor of moved_s
kicks in, and "steals" (i.e. swaps internal pointers etc) the resource of s
, because the latter is a rvalue reference. At the end, s
will not contain any element.