在哪些情况下" std :: move"应该用于"返回"陈述,其中不应该

时间:2015-12-04 12:34:08

标签: c++ move-semantics return-value-optimization

这里有很多类似的问题。在特定情况下,所有人都询问std::movereturn的使用情况。但我想知道std::move语句在return语句中应该(或者不应该)使用的时间。

Here我找到了以下答案:

  

所有返回值都已移动或已优化,因此无需使用返回值显式移动。

     

允许编译器自动移动返回值(以优化副本),甚至优化移动!

所以我期望永远不能在return语句中使用std::move,因为在任何情况下编译器都会优化它。但我决定检查一下并编写以下测试代码:

class A
{
public:
    A() {}
    A(const A  & a) { std::cout << "A(const A  &)" << std::endl; }
    A(      A && a) { std::cout << "A(      A &&)" << std::endl; }
};

A func1(bool first)
{
    A a1, a2;
    return (first ? a1 : a2);
}

int main()
{
    A a1(func1(true));
    return 0;
}

这就是我得到的:

A(const A  &)

所以编译器没有自动移动return语句中的值,我不得不手动移动它:

    return std::move(first ? a1 : a2);

这返回:

A(      A &&)

然而,当我以这种方式重写我的代码时:

A func2(bool first)
{
    A a1, a2;
    if (first) return a1; else return a2;
}

int main()
{
      A a2(func2(true));
      return 0;
}

我发现自动移动有效:

A(      A &&)

下一个测试:

A func3(A &&a)
{
    return a;
}

int main()
{
    A a3(func3(A()));
    return 0;
}

结果:

A(const A  &)

所以必须使用return std::move(a)

接下来我的理解不足了。编译器仅自动移动(甚至使用RVO)局部变量(以及通过值传递的参数(它们实际上也是局部变量))。作为参数传递的Rvalue引用必须手动移动(可能是因为编译器不知道此外部引用是否将在以后的任何地方使用)。编译器也只在“纯”返回语句(return var;)中移动,并且在返回使用局部变量的表达式时不能移动(return <some expression using var>,例如return somefunc(var);)。

所以std::move不应该用于纯粹的&#34;返回本地变量&#34;语句(在这种情况下使用std::move会阻止返回值优化)。在所有其他情况下,std::move中应使用return

我的理解是对的吗?

0 个答案:

没有答案