首页 > 解决方案 > 为什么 C++ 中强制 RVO 需要公共析构函数?

问题描述

请考虑以下简单示例,其中函数bar返回A具有私有析构函数的类对象,并且必须进行强制返回值优化(RVO):

class A { ~A() = default; };
A bar() { return {}; }

该代码被 Clang 接受,但被 GCC 拒绝并出现以下错误:

error: 'constexpr A::~A()' is private within this context
    2 | A bar() { return {}; }
      |                   ^

https://gcc.godbolt.org/z/q6c33absK

哪一个编译器在这里?

标签: c++language-lawyerreturn-value-optimization

解决方案


这是CWG 2426。析构函数可能在此上下文中被调用,因为即使在初始化返回A对象之后,该函数仍有可能无法成功完成:在return语句期间创建的任何临时变量以及范围内的自动局部变量都必须被销毁,如果销毁抛出,那么作为堆栈展开的一部分,A对象被销毁。编译器应该要求此时可以访问析构函数。

注1:函数最外层作用域的局部变量的析构函数抛出的异常可以被函数try块捕获。

注2:返回对象销毁后,允许handler执行另一条return语句。标准中有一个例子。


推荐阅读