有什么区别throw()
和noexcept
其他比分别运行时和编译时,被检查?
这篇Wikipedia C ++ 11文章建议不要使用C ++ 03 throw指定符。
为什么这样,有noexcept
能力在编译时覆盖所有内容?
有什么区别throw()
和noexcept
其他比分别运行时和编译时,被检查?
这篇Wikipedia C ++ 11文章建议不要使用C ++ 03 throw指定符。
为什么这样,有noexcept
能力在编译时覆盖所有内容?
Answers:
不赞成使用异常说明符,因为异常说明符通常是一个糟糕的主意。noexcept
之所以添加它,是因为它是异常说明符的一种合理有用的用法:知道何时函数不会引发异常。因此,它成为二元选择:将要抛出的函数和将不会抛出的函数。
noexcept
被添加,而不是仅仅删除所有的抛出说明符,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()
将在给定类型的默认构造函数引发时抛出。这解决了异常说明符的主要问题之一:它们无法沿调用堆栈向上传播。
您无法使用来做到这一点throw()
。
noexcept
。我从没使用过throw()
说明符,并且一直在尝试确定是否noexcept
确实提供了任何好处(除了编译器检查的文档之外)。
std::terminate
。这是值得担心的!代码可以潜入带有标记功能的发行版中,noexcept
并在运行时(在客户现场)检测到违规情况。我的意思是编译器保证首先生成不会引发异常的代码。
throws()
则如果引发了异常,则必须在terminate()
调用该点(通过unexpected()
)之前将堆栈展开至该函数的范围(这样,该函数中的所有自动变量都将被销毁)。如果标记了函数,noexcept
则如果引发了异常,则调用终止(堆栈的展开是实现定义的细节)。
noexcept
在编译时不检查。
一个实现不应仅仅因为在执行时抛出或可能抛出包含函数不允许的异常而拒绝表达式。
当一个函数被声明noexcept
或throw()
试图抛出异常时,唯一的区别是一个调用terminate
和其他调用unexpected
以及后一种异常处理样式已被有效弃用。
throw()
/ noexcept
,则编译时检查请确保覆盖程序也具有。
noexcept
可能会导致运行时检查。它们之间的主要区别是断裂noexcept
引起std::terminate
而断裂throw
引起std::unexpected
。在这些情况下,堆栈的展开行为也略有不同。