C++03的throw()说明符和C++11的noexcept之间有什么区别

What is the difference between C++03 `throw()` specifier and C++11 `noexcept`?

本文关键字:之间 noexcept 什么 区别 C++11 throw 说明符 C++03      更新时间:2023-10-16

除了在运行时和编译时分别检查之外,throw()noexcept之间有什么区别吗?

这篇Wikipedia C++11文章建议不赞成使用C++03抛出说明符
为什么。。。noexcept是否能够在编译时覆盖所有这些?


注意:我检查了这个问题和这篇文章,但无法确定它被弃用的确切原因。

不赞成使用异常说明符,因为异常说明符通常是一个糟糕的想法。添加noexcept是因为它是异常说明符的一个合理有用的用途:知道函数何时不会抛出异常。因此,它变成了一个二进制选择:将抛出的函数和不抛出的函数。

添加了noexcept,而不是仅仅删除除throw()之外的所有抛出说明符,因为noexcept更强大。noexcept可以有一个编译时解析为布尔值的参数。如果布尔值为true,则noexcept将保持不变。如果布尔值为false,则noexcept不会固定,函数可能会抛出。

因此,你可以这样做:

struct<typename T>
{
void CreateOtherClass() { T t{}; }
};

CreateOtherClass是否抛出异常?如果T的默认构造函数可以的话,它可能会。我们该怎么说?像这样:

struct<typename T>
{
void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; }
};

因此,CreateOtherClass()将抛出给定类型的默认构造函数抛出的iff。这修复了异常说明符的一个主要问题:它们无法向上传播到调用堆栈。

使用throw()无法做到这一点。

noexcept在编译时未检查。

实现不应仅仅因为执行时抛出或可能抛出包含函数不允许的异常而拒绝表达式。

当声明为noexceptthrow()的函数试图抛出异常时,唯一的区别是一个调用terminate,另一个调用unexpected,后一种类型的异常处理实际上已被弃用。

当违反动态异常规范时,C++运行时会调用

std::unexpected():从其异常规范禁止此类型异常的函数抛出异常。

CCD_ 21也可以直接从程序中调用。

在任何一种情况下,std::unexpected都会调用当前安装的std::unexpected_handler。默认的std::unexpected_handler调用std::terminate