C++03 'throw()'说明符和C++11 'noexcept`说明符有什么区别?

xxe27gdn  于 2022-12-20  发布在  其他
关注(0)|答案(3)|浏览(142)

throw()noexcept除了分别在运行时和编译时检查外,还有什么区别吗?
这篇Wikipedia C11文章建议C03抛出说明符被弃用。
为什么会这样...... noexcept是否有足够的能力在编译时涵盖所有这些内容?
注意:我检查了this questionthis article,但无法确定其弃用的可靠原因。

kr98yfug

kr98yfug1#

异常说明符被弃用,因为添加了exception specifiers are generally a terrible idea . noexcept,因为它是异常说明符的一种合理有用的用法:知道什么时候一个函数不会抛出异常,这就变成了一个二元选择:会抛出的函数和不会抛出的函数
添加了noexcept,而不是仅仅删除除throw()之外的所有抛出说明符,因为noexcept功能更强大。noexcept可以有一个参数,该参数在编译时解析为布尔值。如果布尔值为true,则noexcept保留。如果布尔值为false,则noexcept不保留,函数可能抛出。
因此,您可以执行以下操作:

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

CreateOtherClass会抛出异常吗?如果T的默认构造函数可以抛出异常,那么CreateOtherClass可能会抛出异常。我们如何判断呢?比如:

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

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

e1xvtsh3

e1xvtsh32#

编译时不检查noexcept
实现不应仅仅因为表达式在执行时引发或可能引发包含函数不允许的异常而拒绝表达式。
当声明为noexceptthrow()的函数试图抛出异常时,唯一的区别是一个调用terminate,另一个调用unexpected,后一种异常处理风格实际上已经被弃用。

h6my8fg2

h6my8fg23#

std::unexpected()在违反动态异常规范时由C++运行时调用:从其异常规范禁止这种类型的异常的函数抛出异常。
std::unexpected()也可以直接从程序中调用。
在任何一种情况下,std::unexpected都调用当前安装的std::unexpected_handler。默认的std::unexpected_handler调用std::terminate

相关问题