这里有很多类似的问题。在特定情况下,所有人都询问std::move
中return
的使用情况。但我想知道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
。
我的理解是对的吗?