最近的一个问题(尤其是我的回答)让我想起了一个问题:
在C++11(以及更新的标准)中,析构函数总是隐式地noexcept
,除非另有规定(即noexcept(false)
)。在这种情况下,这些析构函数可能合法地抛出异常。(请注意,这仍然是一种“您应该真正知道自己在做什么”的情况!)
然而,在std::unique_ptr<T>::reset()
的所有重载中,都声明为始终是noexcept
(参见cppreference),即使T
的析构函数不是,如果在reset()
期间析构函数抛出异常,则会导致程序终止。类似的情况也适用于std::shared_ptr<T>::reset()
。
为什么reset()
始终是noexcept
,而不是有条件的noexcept
?
它应该可以声明为noexcept(noexcept(std::declval<T>().~T()))
,这样它就只有在T
的析构函数是noexcept
时才是noexcept
的。我在这里错过了什么,还是这是标准中的一个疏漏(因为这显然是一个高度学术的情况)?
T
必须是可销毁的吗?我找不到相关信息。 - el.pescado - нет войнеunique_ptr::reset
可能会抛出异常,那么unique_ptr::~unique_ptr
也可能会抛出异常,然后std::vector<std::unique_ptr>
就不符合标准了,其他所有容器也是如此。这是一个相当糟糕的情况,而且对于使用抛出析构函数的兴趣非常小,因此在标准库中支持它的兴趣也很小。 - Chris Beck