繁体   English   中英

C ++ 11中默认虚拟析构函数的异常规范是什么?

[英]What is the exception specification for a defaulted virtual destructor in C++11?

假设我有:

class Foo
{
public:
   virtual ~Foo()=default;
};

默认析构函数的异常规范是什么? 违约的析构函数是否相当于:

   virtual ~Foo() {};
or
   virtual ~Foo() throw() {};
or
   virtual ~Foo() noexcept {};

C ++ 11标准的第15.4节说它依赖于析构函数的隐式定义直接调用的函数的异常规范。 在这种情况下,没有成员,也没有基类,因此AFAIK没有隐式析构函数直接调用的函数。 这是标准中的含糊不清(或遗漏)吗?

当然,这很重要,因为如果它隐式具有throw(),那么所有子类必须使用throw()声明它们的析构函数。 不要告诉我在析构函数中抛出异常是个坏主意,我知道。 我处理了许多遗留代码,其中根本没有使用异常规范。

作为一个信息点,当我尝试时:

class SubFoo : public Foo
{
public:
   virtual ~SubFoo();
};

我在GCC 4.4中得到了一个错误(不匹配的异常规范)(尽管我承认我可能没有正确的命令行开关),但在使用“11”编译器的XCode 4.3中却没有。

回到同一句话的早期(§15.4/ 14):

...其隐式异常规范指定了type-id T当且仅当T由f的隐式定义直接调用的函数的异常规范允许时; ...“

因此,如果~Foo不调用任何函数,它有一个隐式声明,不允许抛出任何异常。

根据§15.4/ 3:

在以下情况下,两个异常规范兼容:

  • 两者都是非投掷的(见下文),无论其形式如何,

这就是这种情况,因此声明是throw()还是noexcept - 两者在任何情况下都是兼容的。

标准在C ++11§8.4.2/ 2中很好地开始,

如果函数在其第一个声明中明确默认,
- 如果隐式声明是,则隐含地认为是constexpr,
- 它被隐含地认为具有相同的异常规范,就好像它已被隐式声明(15.4),...

但是,在C ++11§15.4/ 14中 ,逻辑迅速转变,

隐式声明的特殊成员函数(第12条)应具有异常规范 如果f是隐式声明的默认构造函数,复制构造函数,移动构造函数,析构函数,复制赋值运算符或移动赋值运算符,则其隐式异常规范指定type-id T当且仅当T被例外规范允许时才由f的隐式定义直接调用的f ; f应允许所有异常,如果它直接调用任何功能允许所有的异常,并f应允许也不例外,如果每次调用直接功能允许没有例外。

在标准的“允许”含义中,它是通过异常规范明确允许的。

如果f调用两个函数,其中一个函数指定并因此允许T ,其中一个函数允许所有异常,则f必须都指定T 允许所有异常,这是不可能的。

所以这绝对看起来像是标准中的缺陷。

我找到了一份相关的缺陷报告, http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1351

然而,看起来这个区域只是一个大混乱。 :-(

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM