RVO 何时保证应用/确实适用于 C++20 编译器

When is RVO garanteed to apply / does apply with C++20 compilers

本文关键字:适用于 C++20 编译器 何时保 应用 RVO      更新时间:2023-10-16

C++核心指南指出

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

但随后给出了以下异常:

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吗?还是不如通过引用传递有效?还是某些编译器无法做到这一点?

更一般地说,我什么时候应该依赖编译器像按引用传递技术一样有效地优化返回值?

">

普通"RVO(即,在通俗的说法中返回prvalue或"临时"(在C++17中得到保证,并且在此之前得到了很好的支持。

NRVO(即返回局部变量(可能很挑剔并且不能保证,如果不执行,那么您将获得移动。如果您的搬家很昂贵,您可能希望避免这种情况。

在此示例中,fill很有可能需要使用后者。

还是仍然不如通过引用传递有效?

如果 RVO 适用,则返回值的效率与使用输出引用的效率相同。

在这种情况下,是否可以阻止RVO?

不。"大"不会阻止对象被 RVO'd。

RVO 何时保证应用/是否适用于 C++20 编译器

不适用的情况:

。return 语句可能涉及调用构造函数来执行操作数的复制或移动(如果它不是 prvalue,或者其类型与函数的返回类型不同(。

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

准则确实没有解释为什么应该遵循这项建议。

请注意,异常显示:

异常

如果一个类型的移动成本很高(例如,array<BigPOD>(,请考虑将其分配给免费存储并返回一个句柄(例如,unique_ptr(,或者将其传递给要填充的非常量目标对象(用作 out-parameter(。

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