这可能是编译器相关的(使用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);
答案 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());
在这种情况下应该调用你的行动。