首页 > 解决方案 > std::function 的目标对象在哪里被禁止抛出破坏?

问题描述

考虑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。此声明被解释为它不在noexceptC++14 中,而是noexcept从 C++17 开始。实现似乎加强了这一点并noexcept在 C++14 中标记(这是允许的):https ://godbolt.org/z/WPh8zs7WE

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

~function();

效果:如果*this != nullptr,破坏这个目标。

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

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

是否在任何地方指定?

还是析构函数function不意味着noexcept?

标签: c++c++17language-lawyerexception-safety

解决方案


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

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

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

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

推荐阅读