C ++ 11: Why is rvalues ​​assignment allowed?

From what I understand, why it is dangerous to return rvalues ​​from functions because of the following code:

T&& f(T&& x) { do_something_to_T(x); return static_cast<T&&>(x); } T f(const T& x) { T x2 = x; do_something_to_T(x2); return x2; } T&& y = f(T()); 

This leaves y as an undefined reference.

However, I do not understand why this code even compiles? Is there a legitimate reason to assign an rvalue link to another rvalue link? Doesn't rvalues ​​mean, roughly speaking, "temporary", i.e. Will be invalidated at the end of the expression? The ability to assign them seems silly to me.

+4
source share
1 answer

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.

+9
source

Source: https://habr.com/ru/post/1398954/


All Articles