【问题标题】:Why is the std::exception destructor not noexcept [duplicate]为什么 std::exception 析构函数不是 noexcept [重复]
【发布时间】:2018-10-06 03:25:04
【问题描述】:

C++11 std::exception 基类的destructor 不是noexcept,因此可能(理论上)抛出异常,从而放宽对其所有派生类的权限(包括std::bad_alloc和std::runtime_error)。然而,C++98 的析构函数std::exception 有一个throw() 异常规范,表明它不允许抛出异常。为什么有区别?为什么现在允许抛出异常?鉴于std::exception constructors 现在是noexcept,该权限特别奇怪:您可以安全地构造这样的对象,但不能安全地销毁它:与正常行为相反。

让异常类的析构函数抛出异常通常是灾难性的。什么会导致std::exception::~exception 抛出异常?

【问题讨论】:

  • cppreference 上显示的声明实际上是noexcept。除非声明为noexcept(false),否则析构函数为noexcept

标签: c++ exception destructor


【解决方案1】:

确实是noexcept(true)。从 C++11 开始,对于没有明确提供异常规范的 destructors,异常规范被认为是 noexcept(true)。

除非没有明确提供异常规范,否则异常规范将被隐式声明的析构函数使用(见下文)。在大多数情况下,这是noexcept(true)。因此必须显式声明一个抛出的析构函数noexcept(false)。 (C++11 起)

【讨论】:

  • 仍然允许恶魔实现通过具有不会是noexcept(true) 的属性来隐式地实现noexcept(false),不是吗?
  • @Holt 它应该与隐式声明的析构函数匹配;对于std::exception,它应该是noexcept(true),除非std::exception是用析构函数为noexcept(false)的基或成员实现的...
【解决方案2】:

[res.on.exception.handling]/3:

C++ 标准库中定义的析构函数操作不得抛出异常。 C++ 标准库中的每个析构函数都应该表现得好像它有一个非抛出异常规范。

【讨论】:

    猜你喜欢
    • 2019-12-09
    • 1970-01-01
    • 2018-06-19
    • 2016-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 2014-05-07
    相关资源
    最近更新 更多