RVO 何时保证适用/确实适用于 C++20 编译器
When is RVO garanteed to apply / does apply with C++20 compilers
C++ 核心指南指出
F.20: For “out” output values, prefer return values to output
parameters
但随后出现以下异常:
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
这不应该是 return 价值优化开始的情况吗?在这种情况下是否阻止了 RVO?或者仍然不如通过引用传递有效?还是某些编译器无法做到这一点?
更一般地说,我什么时候应该依赖 编译器优化 return 值与传递引用技术一样有效?
Or still not as efficient as passing by reference ?
如果应用 RVO,那么 return 一个值与使用输出参考一样有效。
Is RVO prevented in this case?
没有。 “大”不会阻止对象被 RVO。
When is RVO garanteed to apply / does apply with C++20 compilers
不适用的情况:
... A return statement can involve an invocation of a constructor to perform a copy or move of the operand if it is not a prvalue or if its type differs from the return type of the function.
所以,是否保证copy-elision取决于函数的实现。
指南确实无法解释为什么应该遵循建议。
请注意异常显示:
Exceptions
If a type is expensive to move (e.g., array<BigPOD>
), consider allocating it on the free store and return a handle (e.g., unique_ptr), or passing it in a reference to non-const target object to fill (to be used as an out-parameter).
例外中突出显示的建议对我来说更有意义。它清楚地表明对象太大而无法堆栈,从而减少堆栈溢出的机会。
"Plain" RVO(即,返回纯右值或 "temporary" 在普通话中)在 C++17 中得到保证,甚至在此之前就得到了很好的支持。
NRVO(即返回一个局部变量)可能很挑剔并且不能保证,如果它没有执行,那么你会得到一个移动。如果您的搬家费用昂贵,您可能希望避免这种情况。
在示例中,fill
很有可能需要使用后者。
C++ 核心指南指出
F.20: For “out” output values, prefer return values to output parameters
但随后出现以下异常:
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
这不应该是 return 价值优化开始的情况吗?在这种情况下是否阻止了 RVO?或者仍然不如通过引用传递有效?还是某些编译器无法做到这一点?
更一般地说,我什么时候应该依赖 编译器优化 return 值与传递引用技术一样有效?
Or still not as efficient as passing by reference ?
如果应用 RVO,那么 return 一个值与使用输出参考一样有效。
Is RVO prevented in this case?
没有。 “大”不会阻止对象被 RVO。
When is RVO garanteed to apply / does apply with C++20 compilers
不适用的情况:
... A return statement can involve an invocation of a constructor to perform a copy or move of the operand if it is not a prvalue or if its type differs from the return type of the function.
所以,是否保证copy-elision取决于函数的实现。
指南确实无法解释为什么应该遵循建议。
请注意异常显示:
Exceptions
If a type is expensive to move (e.g.,
array<BigPOD>
), consider allocating it on the free store and return a handle (e.g., unique_ptr), or passing it in a reference to non-const target object to fill (to be used as an out-parameter).
例外中突出显示的建议对我来说更有意义。它清楚地表明对象太大而无法堆栈,从而减少堆栈溢出的机会。
"Plain" RVO(即,返回纯右值或 "temporary" 在普通话中)在 C++17 中得到保证,甚至在此之前就得到了很好的支持。
NRVO(即返回一个局部变量)可能很挑剔并且不能保证,如果它没有执行,那么你会得到一个移动。如果您的搬家费用昂贵,您可能希望避免这种情况。
在示例中,fill
很有可能需要使用后者。