and*_*ras 32 c++ destructor language-lawyer noexcept c++11
最近的一个问题(特别是我对它的回答)让我想知道:
在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 ,应该可以声明它使得它完全没有.我在这里遗漏了什么,或者这是标准中的疏忽(因为这无疑是一个高度学术化的情况)?
Nia*_*all 25
调用函数对象Deleter的要求是特定的,如std::unique_ptr<T>::reset()成员的要求中所列.
来自[unique.ptr.single.modifiers]/3,大约N4660§23.11.1.2.5/ 3;
unique_ptr修饰符
void reset(pointer p = pointer()) noexcept;要求:表达式
get_deleter()(get())应格式良好,具有明确定义的行为,不得抛出异常.
通常,类型需要是可破坏的.根据关于C++概念Destructible的cppreference,标准在[utility.arg.requirements]/2,§20.5.3.1(强调我的)中的表下列出了这一点;
Destructible要求
u.~T()所有拥有的资源u都被回收,不会传播任何异常.
另请注意替换功能的一般库要求; [res.on.functions]/2.
std::unique_ptr::reset不会直接调用析构函数,而是调用operator ()deleter模板参数(默认为std::default_delete<T>).该运算符不需要抛出异常,如中所述
23.11.1.2.5 unique_ptr修饰符[unique.ptr.single.modifiers]
void reset(pointer p = pointer()) noexcept;要求:表达式
get_deleter()(get())应格式良好,具有明确定义的行为,不得抛出异常.
注意,不应该抛出不一样noexcept.即使它只调用operator(执行语句)operator (),default_delete也不会声明为.所以这似乎是标准中的一个相当弱点.应该是有条件的noexcept:noexceptdeletedeletereset
noexcept(noexcept(::std::declval<D>()(::std::declval<T*>())))
Run Code Online (Sandbox Code Playgroud)
或operator ()要求删除者noexcept提供更强的保证.
| 归档时间: |
|
| 查看次数: |
2202 次 |
| 最近记录: |