在构建复合对象时消除不必要的副本

Cli*_*ton 2 c++ optimization rvalue-reference c++11

我正在考虑开发一些命名参数代码,但它让我想到了一些如下代码:

#include <utility>

int main() 
{
  using std::make_pair;
  auto x = make_pair(1, make_pair(2, make_pair(3, make_pair(4,5))));
}
Run Code Online (Sandbox Code Playgroud)

现在,一个天真的实现将首先执行"make_pair(4,5)",然后将结果复制到"make_pair(3,...)"的第二个元素中,然后将其复制到"make_pair"的第二个元素中(2,......)"等

不幸的是,这会导致O(n ^ 2)性能,并且会产生大量不必要的副本.我无法看到(命名)返回值优化如何帮助.

理想情况下,make_pair(4,5) 意识到它将在最后一个位置x,并在那个地方构建自己.

更进一步:

#include <utility>

int main() 
{
  using std::make_pair;
  auto&& x1 = make_pair(3, make_pair(4,5));
  auto x2 = make_pair(1, make_pair(2, std::move(x1)));
}
Run Code Online (Sandbox Code Playgroud)

我也想避免像这样的代码中的副本.

这种优化是否如此明显以至于我应该假设编译器执行它或者是否有另一种方法我应该对其进行编码以避免副本?

Jer*_*fin 5

[N] RVO在这种情况下确实有帮助.基本上发生的是一个复合对象被分配,并且每个函数的"返回值"最终直接进入将保存结果的对象.

如果你要做很多事情(特别是在C++ 11中),那么使用元组几乎肯定更干净,更简单,更直接,所以你的:

auto x = make_pair(1, make_pair(2, make_pair(3, make_pair(4,5))));
Run Code Online (Sandbox Code Playgroud)

最终会像:

auto x = make_tuple(1, 2, 3, 4, 5);
Run Code Online (Sandbox Code Playgroud)

这可能不会对生成的代码产生太大影响,但(至少是IMO)它更容易阅读.