Rvalue绑定和移动的组合

Wor*_*der 2 c++ reference c++11

我必须遵循一段代码,我想知道标准对它的说法.它是未定义的行为,定义但未指定的行为或明确定义的行为?

using namespace std;

struct Foo {
    mutable int obj;
    Foo(Foo&&) = default;
    Foo(int arg) : obj(arg) {}
    void f() const { obj *= 2; }
};

int main()
{
    Foo&& a = Foo(5); // Binds temporary, lifetime ends with program
    const Foo& b = a; // Binds a, lifetime ends with program
    Foo c(std::move(a)); // Moves from a
    // a now in defined, but unspecified state
    b.f(); // ??
    cout << b.obj << endl; // May output 10
    return 0;
} // End of lifetime of temporary
Run Code Online (Sandbox Code Playgroud)

注释和我对标准的理解和解释是否正确?

Yak*_*ont 5

move从一个值(rvalue ref构造,而不是std::move自然地调用)语义上意味着该值应该是有效的(特别是对于破坏有效)但是未指定的状态.

但是,move在C++中不做魔术.这正是你应该做的,而不是语言强迫你做的事情.

move原始的"标量"类型实例与复制它没什么不同.

move类类型执行move从源到目标的每个组件的成员(和父级).

=default仅仅意味着"用我的元素的移动构造函数",这是一个int,而此举构造int不...副本(当然,的移动构造函数int不存在,但如果没有它会做一个副本) .

move必须将源保持在有效(并且最重要的是可销毁)状态的语义含义std是以合理的方式与容器和算法交互,以及std类型的行为方式.


一切都很好,但标准支持在哪里?

在这种情况下move使用=default类时会发生什么,最终会出现这个子句:

[class.copy] /15.3

否则,用x的相应基数或成员直接初始化基数或成员

对于直接初始化,告诉您如何int从a 直接初始化的子句int&&是:

[dcl.init] /17.8

否则,正在初始化的对象的初始值是ini-tializer表达式的(可能已转换)值.

第二个表达式的int a = 7; std::move(a);值为7. a由于标准不允许,因此值不会更改.

移动不是魔术.

(n4296,目前的标准草案.)