Why do I need to use std::move in the initialization list of a move-constructor?

本小妞迷上赌 提交于 2019-11-30 11:46:53

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.

Xeo

How is value_(value) different from movable 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!