为什么它不会移动?

Why won't it move?

本文关键字:移动 为什么      更新时间:2023-10-16

这可能是编译器依赖的(使用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);

x是左值,所以当您这样做时:

x = SomeFunc(x);

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

…我不喜欢……

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

是否执行移动取决于如何指示编译器。首先,在一般情况下,编译器本身不会(并且不能)对代码执行语义分析,以确定在调用SomeFunc(x)之后是否需要x

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

SomeFunc(x);         // Does not move
x = SomeFunc(x);     // Moves!?

编译器没有理由在这里调用move函数。Move-ctor可以保证,作为参数传递的对象不会再被使用,而在您的情况下,x是一个局部变量,可以被使用(呸,它用于下面的赋值操作,可以被重载等)。如果显式调用:

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

你冒着使用x被move操作损坏的风险(编译器不会在意,你再次将结果赋值给同一个变量)。

试题:

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

在这种情况下应该调用move函数