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

时间:2012-10-11 06:09:55

标签: c++ exception c++11 throw noexcept

除了分别检查运行时和编译时间之外,throw()noexcept之间是否还有其他区别?

Wikipedia C++11文章表明不推荐使用C ++ 03 throw说明符 为什么这样,noexcept是否足够能够在编译时覆盖所有这些内容?

[注意:我提到了this questionthis article,但无法获得弃用的充分理由。]

3 个答案:

答案 0 :(得分:116)

异常说明符已弃用,因为exception specifiers are generally a terrible idea。添加了noexcept,因为它是一个合理有用的异常说明符:知道函数何时不会抛出异常。因此它成为二元选择:将抛出的函数和不会抛出的函数。

添加了

noexcept而不是仅删除throw()以外的所有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()执行此操作。

答案 1 :(得分:31)

noexcept在编译时没有检查过。

  

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

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

答案 2 :(得分:1)

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

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

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

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