Am I right in assuming that writing
auto && x = ...;
almost never makes sense outside the for (...)
part of a range for, since if the right-hand side indeed is an rvalue, it will normally stop to exist at the semicolon and then x
refers to something that has been destroyed.
In other words:
Widget f () { ... }
...
auto && x = f();
// do something with x
is wrong?
From the standard [class.temporary]:
There are two contexts in which temporaries are destroyed at a different point than the end of the full-expression. The first context is when a default constructor is called to initialize an element of an array.
The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:
— A temporary object bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.
— The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
— A temporary bound to a reference in a new-initializer (5.3.4) persists until the completion of the full-expression containing the new-initializer.
The line auto&& x = f();
falls into that second context, and none of the exceptions apply. Thus, the temporary persists for the lifetime of the reference. So there's nothing wrong with that code.