Home > Enterprise >  Where is it prohibited for target object of std::function to throw on destruction?
Where is it prohibited for target object of std::function to throw on destruction?

Time:10-10

Consider std::function definition:

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

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

    /* ... */

    ~function();

    /* ... */
  };

  /* ... */
}

The destructor is not marked explicitly noexcept. This declaration is interpreted that it is not noexcept in C 14 and it is noexcept starting in C 17. Implementations seem to strengthen this and mark in noexcept in C 14 (which is allowed): https://godbolt.org/z/WPh8zs7WE

The current draft does not say much about destructor, except that it destroys target object. See [func.wrap.func.con]/31:

~function();

Effects: If *this != nullptr, destroys the target of this.

Some requirements for target object are listed in constructor parameter, [func.wrap.func.con]/8 through [func.wrap.func.con]/11. Specifically, it is Lvalue-Callable and Cpp17CopyConstructible.

However I don't see where it is specified that the target object destructor does not throw.

Is it specified anywhere?

Or is destructor of function not meant to be noexcept?

CodePudding user response:

It's a library-wide requirement, specified in [res.on.functions]:

In certain cases ([...], operations on types used to instantiate standard library template components), the C standard library depends on components supplied by a C program. If these components do not meet their requirements, this document places no requirements on the implementation.

In particular, the effects are undefined in the following cases:

  • [...]
  • If any [...] destructor operation exits via an exception, unless specifically allowed in the applicable Required behavior: paragraph.
  • Related