如何使用隐式虚拟析构函数正确解析不兼容的抛出说明符

How to correctly resolve incompatible throw specifiers with implicit virtual destructors?

本文关键字:不兼容 说明符 何使用 虚拟 析构函数      更新时间:2023-10-16

此代码不编译:

#include <QString>
/* relevant part:
struct QString 
{
  ~QString() noexcept(false) {};
};
*/
class Base
{
public:
    virtual ~Base() = default;
};
class Derived : public Base
{
    QString string_;
};
int main()
{
    return 0;
}

错误为:

error: looser throw specifier for 'virtual Derived::~Derived()'
error:   overriding 'virtual Base::~Base() noexcept (true)'

我没有使用异常的经验,但我认为问题是QString析构函数没有异常说明符,因此隐式创建的Derived::~Derived也没有异常说明符。这与作为noexcept(true)的隐式Base::~Base不兼容。

如果我排除了QString或将其替换为具有noexcept(true)的类(如std::string),则代码会编译。

起初,我认为可以通过将两个析构函数都声明为noexcept(false):来解决这个问题

virtual ~Base() noexcept(false) = default;
virtual ~Derived() noexcept(false) = default;

但我得到的只是:

error: function 'virtual Base::~Base()' defaulted on its first declaration 
       with an exception-specification that differs from 
       the implicit declaration 'Base::~Base()'
error: looser throw specifier for 'virtual Derived::~Derived() noexcept (false)'
error: overriding 'virtual Base::~Base() noexcept (true)'

我在代码中的任何地方都不使用异常,所以我要找的只是一个"修复"。

您似乎被指定自己在dtor中抛出的QString激怒了。

我认为没有简单的方法(除了使用一个合理的字符串):您可以随意将基类dtor指定为noexcept(false),或者使派生dtor显式并表示noexcept(true)。(我不确定如果~QString真的抛出了,是否会发生什么好事,但这会导致第一条逃生路线)。