【问题标题】:Where is it prohibited for target object of std::function to throw on destruction?std::function 的目标对象在哪里被禁止抛出破坏?
【发布时间】:2021-10-10 07:19:18
【问题描述】:

考虑std::function定义:

namespace std {
  template<class> class function;       // not defined

  template<class R, class... ArgTypes>
  class function<R(ArgTypes...)> {
  public:
    /* ... */
    template<class F> function(F&&);

    /* ... */

    ~function();

    /* ... */
  };

  /* ... */
}

析构函数没有明确标记noexcept。此声明被解释为在 C++14 中它不是 noexcept,而在 C++17 中它是 noexcept。实现似乎加强了这一点,并在 C++14 中标记 noexcept(这是允许的):https://godbolt.org/z/WPh8zs7WE

目前的草案对析构函数并没有多说,只是它破坏了目标对象。见[func.wrap.func.con]/31:

~function();

效果:如果*this != nullptr,则破坏this的目标。

在构造函数参数[func.wrap.func.con]/8[func.wrap.func.con]/11 中列出了目标对象的一些要求。具体来说就是Lvalue-CallableCpp17CopyConstructible

但是我没有看到指定目标对象析构函数不会抛出的位置。

是否在任何地方指定?

或者function 的析构函数不应该是noexcept?

【问题讨论】:

    标签: c++ c++17 language-lawyer exception-safety


    【解决方案1】:

    这是整个库的要求,在 [res.on.functions] 中指定:

    在某些情况下([...],对用于实例化标准的类型的操作 库模板组件),C++ 标准库依赖于 C++ 程序提供的组件。如果这些组件不满足其要求,则本文档对实施没有任何要求。

    特别是在以下情况下效果是不确定的:

    • [...]
    • 如果任何 [...] 析构函数操作通过异常退出,除非 在适用的必需的行为:段落中特别允许。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-05
      • 2014-05-26
      • 1970-01-01
      • 2010-12-25
      • 2021-05-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多