0

这可能取决于编译器(使用 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);
4

2 回答 2

5

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

x = SomeFunc(x);

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

……我不喜欢那样……

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

是否执行移动取决于如何指示编译器。首先,在一般情况下,单独的编译器不会(也不能)对您的代码执行语义分析,以确定x在调用SomeFunc(x).

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

SomeFunc(x);         // Does not move
x = SomeFunc(x);     // Moves!?
于 2013-03-05T09:44:00.060 回答
1

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

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

您冒着使用 x 进一步被移动操作损坏的风险(编译器不在乎,您再次将结果分配给同一个变量)。

尝试:

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

SomeFunc(ReturnsLargeObject());

在这种情况下应该调用你的 move ctor。

于 2013-03-05T09:44:00.637 回答