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
? 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 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.
Move constructor moves the resources in the heap, i.e., unlike copy constructors which copy the data of the existing object and assigning it to the new object move constructor just makes the pointer of the declared object to point to the data of temporary object and nulls out the pointer of the temporary objects.
std::move() is a function used to convert an lvalue reference into the rvalue reference. Used to move the resources from a source object i.e. for efficient transfer of resources from one object to another.
You have to understand that 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.
B
is the name of an object. Once a reference has been bound, it names an object. The distinction "rvalue reference", "lvalue reference" and "named object" only applies to how the name can be bound before you got this far.B.key
is the name of a variable in the object which was supplied as argument to this function call.
The line A.key = std::move(B.key)
invokes the built-in definition of assignment for an int
(this is a simple assignment, not a function call), which is just a copy. So B.key
retains its value.
For A(B())
to compile, B
must be a typename which you haven't defined yet. (Did you mean A(A())
? If so, then the answer is "Yes").
See 2
Use std::move(Z.foo)
whenever you want to move out of Z.foo
instead of copying from Z.foo
.
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