我正在考虑开发一些命名参数代码,但它让我想到了一些代码,如下所示:
#include <utility>
int main()
{
using std::make_pair;
auto x = make_pair(1, make_pair(2, make_pair(3, make_pair(4,5))));
}
现在,一个天真的实现首先执行“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)));
}
我也想避免像这样的代码副本。
这种优化是否如此明显以至于我应该假设编译器执行它或者是否有另一种方法我应该对其进行编码以避免副本?
答案 0 :(得分:5)
[N] RVO在这种情况下确实有帮助。基本上发生的是一个复合对象被分配,并且每个函数的“返回值”最终直接进入将保存结果的对象。
如果你要做很多事情(尤其是在C ++ 11中),那么使用元组几乎肯定更干净,更简单,更直接,所以你的:
auto x = make_pair(1, make_pair(2, make_pair(3, make_pair(4,5))));
最终会像:
auto x = make_tuple(1, 2, 3, 4, 5);
这可能不会对生成的代码产生太大影响,但(至少是IMO)它更容易阅读。
答案 1 :(得分:1)
make_pair(1, make_pair(2, make_pair(3, make_pair(4,5))));
作为另一个make_pair的参数的所有make_pair将创建一个临时值,该临时值被视为右值引用,因此不会被复制。
我认为你真正想要的是make_tuple。