A recent question (and especially my answer to it) made me wonder:
In C++11 (and newer standards), destructors are always implicitly noexcept
, unless specified otherwise (i.e. noexcept(false)
). In that case, these destructors may legally throw exceptions. (Note that this is still a you should really know what you are doing-kind of situation!)
However, all overloads of
std::unique_ptr<T>::reset()
are declared to always be noexcept
(see cppreference), even if the destructor if T
isn't, resulting in program termination if a destructor throws an exception during reset()
. Similar things apply to std::shared_ptr<T>::reset()
.
Why is reset()
always noexcept, and not conditionally noexcept?
It should be possible to declare it noexcept(noexcept(std::declval<T>().~T()))
which makes it noexcept exactly if the destructor of T
is noexcept. Am I missing something here, or is this an oversight in the standard (since this is admittedly a highly academic situation)?