在许多情况下,当从函数返回一个局部变量时,RVO(返回值优化)就会发挥作用。但是,我认为显式使用std::move
至少会在 RVO 不发生时强制移动,但在可能的情况下仍会应用 RVO。然而,情况似乎并非如此。
#include "iostream"
class HeavyWeight
{
public:
HeavyWeight()
{
std::cout << "ctor" << std::endl;
}
HeavyWeight(const HeavyWeight& other)
{
std::cout << "copy" << std::endl;
}
HeavyWeight(HeavyWeight&& other)
{
std::cout << "move" << std::endl;
}
};
HeavyWeight MakeHeavy()
{
HeavyWeight heavy;
return heavy;
}
int main()
{
auto heavy = MakeHeavy();
return 0;
}
我使用 VC++11 和 GCC 4.71、调试和发布 ( -O2
) 配置测试了这段代码。复制 ctor 永远不会被调用。move ctor 仅在调试配置中由 VC++11 调用。实际上,特别是这些编译器似乎一切都很好,但据我所知,RVO 是可选的。
但是,如果我明确使用move
:
HeavyWeight MakeHeavy()
{
HeavyWeight heavy;
return std::move(heavy);
}
move ctor 总是被调用。因此,试图使其“安全”会使情况变得更糟。
我的问题是:
- 为什么要
std::move
预防 RVO? - 什么时候“希望最好”并依赖 RVO 更好,什么时候应该明确使用
std::move
?或者,换句话说,如果没有应用 RVO,我怎样才能让编译器优化完成它的工作并且仍然强制移动?