im reading this https://leanpub.com/cppmove (C++17 - The Complete Guide First Edition Nicolai M. Josuttisand) and regarding c++17 structured bindings and move semantics it gives the following example, where the moved from object ms
is left intact:
MyStruct ms = { 42, "Jim" }; // struct has fields {int i, std::string s}
auto&& [v,n] = std::move(ms);
// author says: the structured bindings v and n refer to an anonymous
// entity being an rvalue reference to ms, while ms still holds its value:
std::cout << "ms.s: " << ms.s << '\n'; // prints "Jim"
i have tested this, and at least in practical runs, this is true. but is that also generally how it should work? following the way the author gives his previous explanations about structured bindings, the above should be equivalent to
MyStruct ms = { 42, "Jim" };
auto&& e = std::move(ms); // anonymous compiler constructed entity "e"
/*aliasname*/ v = e.i; // v and n act as if e was constructed as
// above and v/n assigned to e.i/e.s as here
/*aliasname*/ n = e.s;
std::cout << "ms.s: " << ms.s << '\n'; // prints "Jim"
question:
so if this is a valid interpretation, would not auto&& e = std::move(ms)
cause ms
to immediately have its contents "moved"/"stolen"/"invalidated"? so that in both (equivalent?) variants above "Jim" is NOT (guaranteed to be) printed...?
clarification: i understand that std::move does not move anything but is a cast from an lvalue to an rvalue, but i would have thought that implied that at least you would not be able to count on the std::move-ed objects (here ms
) contents being retained/available in subsequent uses
marked as dupe of What is std::move(), and when should it be used?. however, with ~300 upvotes, to that question, this answer: https://stackoverflow.com/a/27026280/11608725
The first thing to note is that std::move() doesn't actually move anything. It changes an expression from being an lvalue (such as a named variable) to being an xvalue. An xvalue tells the compiler:
You can plunder me, move anything I'm holding and use it elsewhere (since I'm going to be destroyed soon anyway)".
in other words, when you use std::move(x), you're allowing the compiler to cannibalize x
so i guess confusion is allowed:-P
please recommend a good book for ultradummies on c++17 and move semantics - this book-request most certainly is right-on-topic;-)
would not
auto&& e = std::move(ms)
causems
to immediately have its contents "moved"/"stolen"/"invalidated"?
std::move()
only prepares ms
to be moved, it doesn't outright move from it. That's why e
is a reference to a MyStruct
, not an actual MyStruct
object.