Are rvalues ​​supposed to be, roughly speaking, "temporary", that is, will be declared invalid at the end of the expression?
No, it is not.
Given your function f , this is also legal:
T t{}; T&& y = f(std::move(t));
This is perfectly valid C ++ 11 code. And it also clearly defines what is happening.
The only reason your undefined code is because you are going through temporary. But r-value references should not be temporary.
To develop a little more, a r-value reference is conceptually a reference to a value from which certain operations are considered OK to do otherwise that would not be OK.
References to an R-value are very carefully specified in C ++ 11. A reference to an l-value can be tied to any non-temporary without the need for a cast or something:
T t{}; T &y = t;
A reference to an r-value may be implicitly associated with a temporary or other "xvalue" (an object that is likely to leave in the near future):
T &&x = T{}; T &&no = t; //Fail.
To bind a r-value reference to a non-value, you need to do an explicit cast. The way C ++ 11 calls this cast is saying: std::move :
T &&yes = std::move(t);
“Some of the operations that I talked about were“ moving. ”It's normal to go from an object in two conditions:
- He will leave anyway. IE: temporary.
- The user explicitly said to switch from him.
And these are just two cases where a reference to an r-value can be associated with something.
There are exactly two reasons why references to the r-value exist: support for semantics of movement and support for perfect forwarding (which requires a new reference type on which they can impose funk-casting mechanics, as well as potentially move semantics). Therefore, if you do not perform one of these two operations, the reasons for using && uncertain.
In fact, I even went so far as to say that parameters should be && only in two cases: the forwarding function or the constructor / destination of the move. In all other cases, if you want to allow movement, you take the type by value, and not by && . This way you force it to move as part of a function call. An object can be moved from there to its final destination.