首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么时候RVO需要在C++20编译器中应用/确实应用

什么时候RVO需要在C++20编译器中应用/确实应用
EN

Stack Overflow用户
提问于 2019-10-06 22:49:18
回答 2查看 269关注 0票数 7

C++的核心指南指出:

F.20:对于“out”输出值,首选返回值而不是输出参数

但随后给出了以下例外:

代码语言:javascript
复制
struct Package {      // exceptional case: expensive-to-move object
    char header[16];
    char load[2024 - 16];
};

Package fill();       // Bad: large return value
void fill(Package&);  // OK

它不应该是返回值优化开始的情况吗?在这种情况下,RVO被阻止了吗?还是仍然没有参考传递的效率高?或者是某些编译器无法做到这一点?

更普遍地说,我应该在什么时候依赖于编译器对返回值的优化,就像按引用传递技术一样高效?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-06 23:50:35

“纯正”RVO (即返回prvalue或通用术语中的“临时”)在C++17中得到了保证,甚至在此之前就得到了良好的支持。

NRVO (即返回一个局部变量)可能很挑剔,也不能保证,如果它没有执行,那么您将得到一个移动。如果你的搬家是昂贵的,你可能想要避免这种情况。

在这个例子中,fill很可能需要使用后者。

票数 4
EN

Stack Overflow用户

发布于 2019-10-06 23:45:01

还是仍然没有引用传递的效率高?

如果应用RVO,则返回值与使用输出引用一样有效。

在这种情况下,

被阻止了吗?

不是的。“大”并不能阻止对象成为RVO'd。

何时被C++20编译器应用/确实应用?

不适用的情况:

...如果操作数不是prvalue,或者其类型与函数的返回类型不同,则返回语句可以包含对构造函数的调用来执行操作数的复制或移动。

因此,这取决于该函数的实现是否保证复制。

这些指导方针确实无法解释为什么要遵循建议。

请注意,例外情况如下:

例外

如果一个类型移动成本很高(例如,array<BigPOD>**),考虑在空闲存储上分配它并返回一个句柄(例如,unique_ptr)**,或者在引用中将它传递给非const目标对象以填充(用作输出参数)。

例外中突出的建议对我来说更有意义。它清楚地表明,对象太大,不能堆栈,从而减少了堆栈溢出的机会。

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

https://stackoverflow.com/questions/58261835

复制
相关文章

相似问题

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