在 C++03 理论中:
如果你抛出一个不在异常规范中的异常,unexpected()
就会被调用。如果您没有通过set_unexpected()
这种方式设置意外处理程序terminate()
,则会调用您观察到的情况。如果您设置了一个不调用终止但抛出异常的意外处理程序,并且如果该异常未在您的异常规范中列出,它将被转换为 bad_exception。因此,为了获得预期的结果,set_unexpected()
首先使用适当的处理程序进行调用。
在 C++03 实践中:
一些编译器根本不支持异常规范(除了throw()
),其他编译器只是不评估/检查它们的正确性。正如Herb Sutter 所指出的,异常规范创建了一个笨拙的“影子类型系统”,不容易正确处理(如果可能的话)。所以..
... 在 C++11 中:不推荐使用
异常规范。你不应该使用它们。但是,有一个nothrow
运算符的功能与throw()
PS:那么为什么在 C++03 中有 std::bad_exception 呢?
您有三个不同的代码区域:
- 您正在为其编写异常规范的函数。
- 您从该函数调用的“外部”代码可能会或可能不会引发与您的规范不匹配的异常。
- (可能也是未知的)意外处理程序可以是任何东西,应该终止/退出/中止程序或抛出任何东西。
因此,如果“外部”代码抛出了违反您的异常规范的异常,您可能会出现以下三种结果:
- 处理程序终止程序。除非您在函数中设置自己的处理程序,否则您无能为力。
- 处理程序抛出与您的异常规范匹配的异常。一切都很好。
- 处理程序抛出其他东西。您希望运行时现在做什么?这就是 bad_exception 出现的地方:如果它在您的规范中,则“其他内容”会被转换为 bad_exception,然后程序继续。如果不是,则调用 terminate。
在函数中设置您自己的处理程序会禁用之前由只想使用您的函数的任何其他人设置的任何处理程序。他不会期望你禁用他的处理程序。此外,处理程序是一个全局的what-happens-if 策略,因此在单个函数实现中你不应该关心任何事情。