C++17下static_cast<T>(funcReturningT())是否会抑制RVO拷贝消除?
结论
C++17及更高版本的标准仍然保证该场景下的强制拷贝消除。
规则依据
- C++17引入的强制拷贝消除核心触发条件为:用同类型的纯右值(prvalue)初始化对象时,编译器必须省略中间的拷贝/移动构造流程,直接在目标对象的内存地址上构造对应值,该过程不要求拷贝/移动构造函数存在或可访问。
- 原生场景中
funcReturningT()返回值为T类型纯右值,完全符合上述触发条件,拷贝消除被强制保证。 - 对于加了
static_cast<T>的写法:当static_cast的目标类型与输入操作数类型完全一致、且操作数为纯右值时,static_cast<T>(funcReturningT())的返回结果仍然是T类型的纯右值,和直接调用funcReturningT()的语义等价,仍然满足强制拷贝消除的触发要求。
注意:以上强制保证仅适用于C17及更高版本。C14及更早标准中拷贝消除属于可选编译器优化,无论是否添加
static_cast包裹,都不被标准强制要求生效。
验证示例
你可以用以下代码验证该规则:
#include <iostream> struct T { T() { std::cout << "构造函数调用\n"; } T(const T&) = delete; // 禁用拷贝构造 T(T&&) = delete; // 禁用移动构造 }; T funcReturningT() { return T(); } int main() { // 两种写法在C++17标准下均可以正常编译运行 T t1 = funcReturningT(); T t2 = static_cast<T>(funcReturningT()); return 0; }
如果拷贝消除不生效,因为拷贝、移动构造都被禁用,代码会编译失败。符合C++17标准的编译器编译该代码时,只会输出两次构造函数调用,没有任何额外的拷贝/移动操作执行。
内容的提问来源于stack exchange,提问作者Arno Schoedl
相关产品推荐
相关产品推荐

