Let\'s say I have a (trivial) class, which is move-constructible and move-assignable but not copy-constructable or copy-assignable:
class movable
{
public:
How is
value_(value)
different frommovable m1(movable(42))
?
A named rvalue reference is an lvalue (and will thus bind to the deleted copy ctor), while a temporary is, well, an rvalue (a prvalue to be specific).
§5 [expr] p6
[...] In general, the effect of this rule is that named rvalue references are treated as lvalues and unnamed rvalue references to objects are treated as xvalues [...]
Aswell as from the example:
A&& ar = static_cast<A&&>(a);
The expression
ar
is an lvalue.
The above quotes are from non-normative notes, but are an adequate explanation, since the rest of clause 5 goes and explains which expressions only create xvalues† (aka, only the specified expressions and none else will create xvalues). See also here for an exhaustive list.
† xvalues are one subgroup of rvalues, with prvalues being the other subgroup. See this question for an explanation.
That's because value
is a named variable, and thus an lvalue. The std::move
is required to cast it back into an rvalue, so that it will cause move-constructor overload of T
to match.
To say it another way: An rvalue reference can bind to an rvalue, but it is not itself an rvalue. It's just a reference, and in an expression it is an lvalue. The only way to create from it an expression that is an rvalue is by casting.