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.