106

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

这篇 Wikipedia C++11 文章建议弃用 C++03 抛出说明符。
为什么这样,noexcept有足够的能力在编译时涵盖所有这些?

[注意:我检查了这个问题这篇文章,但无法确定弃用的充分理由。]

4

3 回答 3

139

异常说明符已被弃用,因为异常说明符通常是一个糟糕的主意noexcept之所以添加它,是因为它是异常说明符的一种合理有用的用法:知道函数何时不会抛出异常。因此它变成了一个二元选择:会抛出的函数和不会抛出的函数。

noexcept添加而不是仅仅删除所有抛出说明符,而不是throw()因为noexcept更强大。noexcept可以有一个编译时解析为布尔值的参数。如果布尔值是真的,那么noexcept棒。如果布尔值是假的,那么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()如果给定类型的默认构造函数抛出,将抛出。这解决了异常说明符的主要问题之一:它们无法向上传播调用堆栈。

你不能用throw().

于 2012-10-11T06:23:36.820 回答
34

noexcept在编译时不检查。

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

当一个函数被声明noexceptthrow()试图抛出异常时,唯一的区别是一个调用terminate和另一个调用unexpected,并且后一种异常处理方式已被有效地弃用。

于 2012-10-11T06:23:58.723 回答
2

std::unexpected()当违反动态异常规范时由 C++ 运行时调用:从其异常规范禁止此类异常的函数抛出异常。

std::unexpected()也可以直接从程序中调用。

无论哪种情况,std::unexpected调用当前安装的std::unexpected_handler. 默认std::unexpected_handler调用std::terminate.

于 2017-07-10T17:08:13.120 回答