As skypjack correctly comments, accessing an object through its name always results in an lvalue reference.
This is a safety feature and if you think it through you will realise that you are glad of it.
As you know, std::move
simply casts an l-value reference to an r-value reference. If we use the returned r-value reference immediately (i.e. un-named) then it remains an r-value reference.
This means that the use of the r-value can only be at the point in the code where move(x)
is mentioned. From a code-reader's perspective, it's now easy to see where x's state became undefined.
so:
1: auto x = make_x();
2: auto&& r = std::move(x);
3: // lots of other stuff
35: // ...
54: // ...
55: take_my_x(r);
does not work. If it did, someone maintaining the code would have a hard time seeing (and remembering) that x (defined on line 1) enters an undefined state on line 55 through a reference taken on line 2.
This is a good deal more explicit:
1: auto x = make_x();
2: //
3: // lots of other stuff
35: // ...
54: // ...
55: take_my_x(std::move(x));