How does the rvalue parameter work?

So, I was just really surprised to find that in this code:

void AddLayer( shared_Layer_ptr && pNewLayer_p ){ m_layers.push_back( pNewLayer_p ); // * } 

Push_back is called - this is "& param", not the version of "& & param". m_layers is a std :: vector. Since pNewLayer_p is "& &", I though it was a damn rvalue. The only way I get push_back ("& & param") is called using std :: move:

 m_layers.push_back( std::move(pNewLayer_p) ); 

It seems redundant to me since pNewLayer_p is already "& &". I'm sure something is missing, what is it?

+4
source share
2 answers

pNewLayer_p is a reference to rvalue, but it is not rvalue itself - mainly because it has a name. In the standard, the values ​​of R are defined as follows:

(3.10 / 1) An Rvalue (so-called, historically, because rvalues ​​can appear on the right side of an assignment expression) is an xvalue, a temporary object (12.2), or a subobject or value that is not associated with the object.

In other words, rvalues ​​are literals, temporary and other unidentified objects (such as xvalues, that is, values ​​that have just been returned by a function but not yet assigned).

The rvalue pNewLayer_p in your code is a named object, so it is itself an lvalue. Applying std::move to it, which formally is a function, turns it (formally) into something returned by the function, that is, the value of x, which is the r-value that you can pass to the push_back engine version. There is std::move .

(Note: The above assumes that shared_Layer_ptr is a type, not a template parameter. If it is a template parameter, shared_Layer_ptr && will be the so-called universal reference, that is, it can be a reference to lvalue or rvalue depending on how the template is instantiated. In this case std::forward would be a suitable function to use instead of std::move .)

+2
source

Think about what happens if it moves pNewLayer .

 void AddLayer( shared_Layer_ptr && pNewLayer_p ){ m_layers.push_back( pNewLayer_p ); // what if pNewLayer_p is already moved another_m_layers.push_back( pNewLayer_p ); } 

Therefore, you should explicitly use std::move :

 void AddLayer( shared_Layer_ptr && pNewLayer_p ){ m_layers.push_back( pNewLayer_p ); another_m_layers.push_back( std::move(pNewLayer_p) ); } 

If a rvalue reference can only appear once in a function, this will definitely remove some power from C ++.

+2
source

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


All Articles