C++的核心指南指出:
F.20:对于“out”输出值,首选返回值而不是输出参数
但随后给出了以下例外:
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被阻止了吗?还是仍然没有参考传递的效率高?或者是某些编译器无法做到这一点?
更普遍地说,我应该在什么时候依赖于编译器对返回值的优化,就像按引用传递技术一样高效?
发布于 2019-10-06 23:50:35
“纯正”RVO (即返回prvalue或通用术语中的“临时”)在C++17中得到了保证,甚至在此之前就得到了良好的支持。
NRVO (即返回一个局部变量)可能很挑剔,也不能保证,如果它没有执行,那么您将得到一个移动。如果你的搬家是昂贵的,你可能想要避免这种情况。
在这个例子中,fill很可能需要使用后者。
发布于 2019-10-06 23:45:01
还是仍然没有引用传递的效率高?
如果应用RVO,则返回值与使用输出引用一样有效。
在这种情况下,
被阻止了吗?
不是的。“大”并不能阻止对象成为RVO'd。
何时被C++20编译器应用/确实应用?
不适用的情况:
...如果操作数不是prvalue,或者其类型与函数的返回类型不同,则返回语句可以包含对构造函数的调用来执行操作数的复制或移动。
因此,这取决于该函数的实现是否保证复制。
这些指导方针确实无法解释为什么要遵循建议。
请注意,例外情况如下:
例外
如果一个类型移动成本很高(例如,array<BigPOD>**),考虑在空闲存储上分配它并返回一个句柄(例如,unique_ptr)**,或者在引用中将它传递给非const目标对象以填充(用作输出参数)。
例外中突出的建议对我来说更有意义。它清楚地表明,对象太大,不能堆栈,从而减少了堆栈溢出的机会。
https://stackoverflow.com/questions/58261835
复制相似问题