c++17 structured bindings and move semantics

763 Views Asked by At

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;-)

1

There are 1 best solutions below

0
On BEST ANSWER

would not auto&& e = std::move(ms) cause ms 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.