The documentation says that Deleter should be:
~unique_ptr() noexcept
My question is why uniqut_ptr
is defined to allow a Deleter
that may throw. E.g. the following Deleter
is allowed by all unique_ptr
constructors:
struct BadDeleter
{
BadDeleter() noexcept(false) {}
~BadDeleter() noexcept(false) {}
BadDeleter(const BadDeleter&) noexcept(false) {}
BadDeleter(BadDeleter&) noexcept(false) {}
BadDeleter(BadDeleter&&) noexcept(false) {}
void operator()(char* p) const noexcept(false) {
delete p;
};
};
The standard only defines the requirements on a uniqe_ptr
's deleter based on the unique_ptr
's operations. While those requirements always say things like
~unique_ptr();
Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behavior, and shall not throw exceptions.
the standard never explicitly specifies that the deleter must have a noexcept
operator()
.
I presume this wording was chosen to remain backwards-compatible with C++14. In that standard, noexcept
was not part of a function's signature, and adding that requirement in C++17 likely would have broken a lot of code where custom deleters were used without explicitly marking their operations as noexcept
.