为什么不动呢?

时间:2013-03-05 09:40:22

标签: c++ visual-studio-2010 c++11

这可能是编译器相关的(使用VS2010),或者没有,但为什么以下操作不会调用预期的移动行为:

LargeObject x;
x = SomeFunc(x);

我已将该函数定义为对

LargeObject SomeFunc(const LargeObject& ob)
{
    LargeObject newOb;
    // perform operation on new object using old object
    return newOb;
}

LargeObject SomeFunc(LargeObject&& ob)
{
    // change object directly...
    return std::move(ob);
}

我明确需要写

x = SomeFunc(std::move(x));

让它成为现实,我不喜欢......

编辑:第一个使用const-ref的函数是因为我还需要做像

这样的事情
LargeObject x;
LargeObject y = SomeFunc(x);

2 个答案:

答案 0 :(得分:5)

x是一个左值,所以当你这样做时:

x = SomeFunc(x);

选择接受对const的左值引用的重载,因为右值引用不能绑定到左值。如果您希望选择第二个重载,则必须以某种方式将x转换为右值。这就是std::move的作用。

  

......我不喜欢那样......

我相信如果将对象传递给一个隐含意味着移动它的函数,你会更喜欢它!

是否执行移动取决于指示编译器的方式。首先,在一般情况下,单独的编译器不会(并且不能)对您的代码执行语义分析,以确定在调用{{}后是否需要x 1}}。

此外,如果以下两条指令在传递参数时导致不同的行为,那将是非常奇怪的:

SomeFunc(x)

答案 1 :(得分:1)

没有理由,为什么编译器应该在这里调用一个移动ctor。 Move-ctor得到保证,作为参数传递的对象不会再被使用,而在你的情况下,x是一个局部变量而可以被使用(bah,它是< / em>用于以下赋值操作,可以重载等)。如果你明确打电话:

x = SomeFunc(std::move(x));

你冒险使用进一步移动操作损坏的x(编译器不关心,你再次将结果分配给同一个变量)。

尝试:

LargeObject ReturnsLargeObject()
{
    LargeObject x;
    return x;
}

SomeFunc(ReturnsLargeObject());

在这种情况下应该调用你的行动。