In C ++ 11, I understand that by default, destructors are implicitly noexcept(true) , except that:
If I have a class C whose destructor is explicitly labeled noexcept(false) (presumably because it throws for some odd reason, and I know you shouldn't and why), then the destructor of any class that comes from C or contains an element of type C , it also becomes noexcept(false) .
However, the class containing std::shared_ptr<C> does not seem to automatically disable its destructor to noexcept(false) , and the same is true to contain std::weak_ptr<C> , std::unique_ptr<C> etc.
Here is a complete example:
#include <type_traits> #include <memory> struct Normal { ~Normal() { } }; struct ThrowsInDtor { ~ThrowsInDtor() noexcept(false) { throw 42; } }; template<typename T> struct Wrapper { T t; }; template<typename T> struct UniquePtrWrapper { std::unique_ptr<T> t; }; template<typename T> struct SharedPtrWrapper { std::shared_ptr<T> t; }; static_assert(std::is_nothrow_destructible<Normal>::value, "A"); // OK static_assert(!std::is_nothrow_destructible<ThrowsInDtor>::value, "B"); // OK static_assert(std::is_nothrow_destructible<Wrapper<Normal>>::value, "C"); // OK static_assert(!std::is_nothrow_destructible<Wrapper<ThrowsInDtor>>::value, "D"); // OK static_assert(std::is_nothrow_destructible<UniquePtrWrapper<Normal>>::value, "E"); // OK static_assert(!std::is_nothrow_destructible<UniquePtrWrapper<ThrowsInDtor>>::value, "F"); // FAILS static_assert(std::is_nothrow_destructible<SharedPtrWrapper<Normal>>::value, "G"); // OK static_assert(!std::is_nothrow_destructible<SharedPtrWrapper<ThrowsInDtor>>::value, "H"); // FAILS
It seems strange to me that F and H fail. I expected that the noexcept destructor status of the owned / reference type would extend to the smart pointer destructor, presumably through a noexcept expression such as noexcept(std::is_nothrow_destructible<T>::value) in the smart pointer destructor declaration.
However, the standard does not mention this, and the standard library code I was looking at does not.
Does anyone know why standard smart pointers do not propagate the noexcept instance type destructor status to the smart pointer destructor?