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
.)