So I just got really surprised to find that in this code:
void AddLayer( shared_Layer_ptr && pNewLayer_p ){
m_layers.push_back( pNewLayer_p ); // *
}
The push_back being called is the "& param", not the "&& param" version. m_layers is a std::vector. Since pNewLayer_p is a "&&", I though it was a damn rvalue..The only way I manage to get the push_back("&& param") called is by using std::move:
m_layers.push_back( std::move(pNewLayer_p) );
To me seems redundant since pNewLayer_p is already a "&&".. Im sure missing something, what is it?
pNewLayer_p
is an rvalue reference, but it is not an rvalue itself – basically because it has a name. Rvalues are defined as follows in the Standard:
(3.10/1) An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment expression) is an xvalue, a temporary object (12.2) or subobject thereof, or a value that is not associated with an object.
In other words, rvalues are literals, temporaries and otherwise unnamed objects (such as xvalues, i.e. values that have just been returned by a function, but not been assigned to anything yet).
The rvalue reference pNewLayer_p
in your code is a named object, so it is itself an lvalue. Applying std::move
to it, which is formally a function, turns it (formally) into something returned from a function, i.e. an xvalue, which is an rvalue that you can pass to the move-version of push_back
. This is what std::move
exists for.
(Note: The above assumes that shared_Layer_ptr
is a type, not a template parameter. If it is a template parameter, shared_Layer_ptr &&
would be a so-called universal reference, i.e. it may be an lvalue reference or an rvalue reference depending on how the template is instantiated. In this case, std::forward
would be the appropriate function to use instead of std::move
.)