From the move page of the cppreference
Unless otherwise specified, all standard library objects that have been moved from are placed in a valid but unspecified state. That is, only the functions without preconditions, such as the assignment operator, can be safely used on the object after it was moved from
So, from the example on the same page, this code below is considered undefined behaviour
vector<string> v_string;
string example = "example";
v_string.push_back(move(example));
cout << example << endl;
MSVC will output nothing on the console, but if I do this
vector<int> v_int;
int number = 10;
v_int.push_back(move(number));
cout << number << endl;
will output 10. Is there a reason why this happens? Or is it always undefined behavior?
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 And Semantics: 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.
Does std::move invalidate pointers? No. An object still exists after being moved from, so any pointers to that object are still valid.
A: You should use std::move if you want to call functions that support move semantics with an argument which is not an rvalue (temporary expression).
Unspecified does not mean undefined.
According to the C++11 standard, section 17.3.26:
valid but unspecified state an object state that is not specified except that the object’s invariants are met and operations on the object behave as specified for its type
As the object is in a valid state, you can stream it to an output, as streaming has no additional preconditions. However what is printed is unspecified, so it may just print nothing, or print that your father smells of elderberries. What you can not safely do is use a function with additional preconditions such as back()
which additionally requires the string to be non-empty. Valid strings can be empty.
Containing the old value is a perfectly acceptable option for the unspecified but valid state. In case of fundamental types such as int
a simple copy is just the most efficient way to perform a move.
It should also be noted that int
is not a standard library object, but a fundamental type (as defined in section 3.9.1). Therefore your quote does not apply.
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