C ++之间的差异03 throw()说明符C ++ 11 noexcept
除了分别检查运行时和编译时间之外, throw()
和noexcept
之间是否还有其他区别?
维基百科的C ++ 11文章指出,C ++ 03抛出说明符已被弃用。
为什么noexcept
能够在编译时覆盖所有的内容呢?
[注意:我把这个问题和这篇文章提到了 ,但是拿不到折服的可靠原因。]
exception说明符已被弃用,因为exception说明符通常是一个可怕的想法 。 noexcept
被添加,因为它是一个合理有用的exception说明符的用法:知道函数何时不会抛出exception。 因此它变成了一个二元select:抛出的函数和不会抛出的函数。
添加了noexcept
而不是仅仅删除throw()
以外的所有throw指示符,因为noexcept
更强大。 noexcept
可以有一个编译时parsing成布尔值的参数。 如果布尔值为true,那么noexcept
坚持。 如果布尔值为false,则noexcept
不会粘住,并且可能抛出该函数。
因此,你可以做这样的事情:
struct<typename T> { void CreateOtherClass() { T t{}; } };
CreateOtherClass
是否CreateOtherClass
抛出exception? 它可能,如果T
的默认构造函数可以。 我们怎么看? 喜欢这个:
struct<typename T> { void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; } };
因此,如果给定types的默认构造函数抛出, CreateOtherClass()
将抛出。 这解决了exception说明符的一个主要问题:它们无法传播调用堆栈。
你不能用throw()
来做到这一点。
在编译时不检查noexcept
。
一个实现不应该仅仅因为在执行时抛出一个expression式,或者可能抛出一个包含函数不允许的exception。
当一个被声明为noexcept
或者throw()
的函数试图抛出一个exception时,唯一的区别是调用terminate
和其他调用是unexpected
,后一种exception处理方式已经被有效的使用了。
当违反dynamicexception规范时,std :: unexpected()被C ++运行时调用:exception从一个函数中抛出,其exception说明禁止这种types的exception。
std :: unexpected()也可以直接从程序中调用。
在任何一种情况下,std :: unexpected都会调用当前安装的std :: unexpected_handler。 默认的std :: unexpected_handler调用std :: terminate。