除了分别检查运行时和编译时间之外,throw()
和noexcept
之间是否还有其他区别?
Wikipedia C++11文章表明不推荐使用C ++ 03 throw说明符
为什么这样,noexcept
是否足够能够在编译时覆盖所有这些内容?
[注意:我提到了this question和this article,但无法获得弃用的充分理由。]
答案 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
在编译时没有检查过。
实现不应仅仅因为执行时抛出或抛出包含函数不允许的异常而拒绝表达式。
当声明为noexcept
或throw()
的函数尝试抛出异常时,唯一的区别是一个调用terminate
和另一个调用unexpected
而后者调用异常处理实际上已被弃用。
答案 2 :(得分:1)
std :: unexpected():从异常规范禁止此类异常的函数抛出异常。
std :: unexpected()也可以直接从程序中调用。
在任何一种情况下,std :: unexpected都会调用当前安装的std :: unexpected_handler。默认的std :: unexpected_handler调用std :: terminate。