首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >返回std::pair时会发生RVO吗?

返回std::pair时会发生RVO吗?
EN

Stack Overflow用户
提问于 2012-12-27 00:55:39
回答 4查看 1.2K关注 0票数 9

函数需要向调用者返回两个值。最好的实现方式是什么?

选项1:

代码语言:javascript
运行
复制
pair<U,V> myfunc()
{
...
return make_pair(getU(),getV());
}

pair<U,V> mypair = myfunc();

选项1.1:

代码语言:javascript
运行
复制
// Same defn
U u; V v;
tie(u,v) = myfunc();

选项2:

代码语言:javascript
运行
复制
void myfunc(U& u , V& v)
{
u = getU(); v= getV();
}

U u; V v;
myfunc(u,v);

我知道Option2没有拷贝/移动,但它看起来很丑陋。在Option1 1.1中会发生任何拷贝/移动吗?让我们假设U和V都是支持复制/移动操作的巨大对象。

问:根据标准,理论上是否可以进行任何RVO/NRVO优化?如果是,gcc或其他编译器已经实现了吗?

EN

回答 4

Stack Overflow用户

发布于 2012-12-27 01:06:40

返回

std::pair**?**时,是否会发生RVO

是的,它可以。

这肯定会发生吗?

不,不是。

C++11标准:第12.8/31节:

当满足某些条件时,允许实现省略类对象的复制/移动构造,即使对象的复制/移动构造函数和/或析构函数具有副作用。

复制省略并不是一个有保证的功能。这是一种允许编译器在任何时候执行的优化。没有什么特别的w.r.t std::pair。如果编译器足够好,可以检测到优化机会,它就会这么做。所以你的问题是特定于编译器的,但是的,同样的规则也适用于std::pair和任何其他类。

票数 8
EN

Stack Overflow用户

发布于 2012-12-27 11:07:40

虽然不能保证RVO,但在C++11中,我认为您定义的函数至少必须移动-返回,所以我建议保留更清晰的定义,而不是扭曲它以接受输出变量(除非您有使用它们的特定策略)。

此外,即使本例使用了RVO,显式地使用make_pair也意味着您将始终至少有一个额外的对构造,从而执行移动操作。将其更改为返回花括号初始化的表达式:

代码语言:javascript
运行
复制
return { getU(), getV() };
票数 4
EN

Stack Overflow用户

发布于 2012-12-27 01:14:48

RVO或复制省略依赖于编译器,所以如果你想拥有RVO并避免调用复制构造函数,最好的选择是使用指针。

在我们的产品中,我们使用指针和boost容器指针来避免复制构造函数。这确实带来了大约10%的性能提升。

对于你的问题,在选项1中,U和V的拷贝构造函数不会被调用,因为你不是返回U或V,而是返回std::pair对象,所以它的拷贝构造函数将被调用,大多数编译器在这里肯定会使用RVO来避免这种情况。

谢谢Niraj Rathi

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14043609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档