0

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?

Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79

1 Answers1

2

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.
Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157