Rvalue绑定和移动的组合

时间:2015-02-11 15:16:13

标签: c++ c++11 reference

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

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

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

1 个答案:

答案 0 :(得分:5)

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

然而,C ++中的move并没有做出魔法。这正是你应该做的事情,而不是语言强迫你做的事情。

move一个原始的&#34;标量&#34;类型实例与复制它没什么不同。

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

=default只是意味着&#34;使用我的元素&#34;的移动构造函数,这是一个intint的移动构造函数做...复制(好吧,int的移动构造函数不存在,但是如果它存在则会复制)。

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


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

在这种情况下move使用=default一个类时,会发生什么结果:

[class.copy] /15.3

  

否则,基础或成员用相应的基础或x

成员直接初始化

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

[dcl.init] /17.8

  

否则,初始化对象的初始值是初始化表达式的(可能已转换)值。

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

移动并不神奇。

n4296引用,目前的标准草案。)