谁能告诉我何时调用终止()以及何时调用意外()?
在您的情况下,将调用您的终止处理程序。您可以在此处验证这一点。
关于std::terminate()
,第 15.5.1/1-2 段包含一个注释,其中列出了它被调用的情况的非常详尽的列表(粗体部分适用于您的情况):
1 在某些情况下,必须放弃异常处理以使用不太微妙的错误处理技术。[注:这些情况是:
— 当异常处理机制在完成异常对象的初始化之后但在激活异常处理程序之前(15.1)调用通过异常退出的函数,或
—当异常处理机制无法找到抛出异常的处理程序时(15.3),或
— 当搜索处理程序 (15.3) 遇到具有不允许异常 (15.4) 的 noexcept 规范的函数的最外层块时,或
— 当堆栈展开(15.2)期间对象的破坏因抛出异常而终止时,或
— 当具有静态或线程存储持续时间(3.6.2)的非局部变量的初始化通过异常退出时,或
— 当通过异常(3.6.3)退出具有静态或线程存储持续时间的对象时,或
— 当执行注册std::atexit
或std::at_quick_exit
通过异常(18.5)退出的函数时,或
— 当没有操作数的 throw 表达式尝试重新抛出异常并且没有处理异常时 (15.1),或
— 当std::unexpected
抛出先前违反的动态异常规范不允许的异常,并且 std::bad_exception 不包含在该动态异常规范 (15.5.2) 中,或
— 当调用实现的默认意外异常处理程序时 (D.11.1),或
— 当std::nested_exception::rethrow_nested
为未捕获异常的对象调用函数时(18.8.6),或
— 当线程的初始函数的执行通过异常(30.3.1.2)退出时,或
— 当在 std::thread 类型的对象上调用析构函数或复制赋值运算符时,该对象引用可连接线程(30.3.1.3、30.3.1.4)。——尾注]
2 在这种情况下,std::terminate()
称为 (18.8.3)。[...]
关于std::unexpected()
,根据第 15.4/9 段:
每当抛出异常并且搜索处理程序 (15.3) 遇到具有不允许异常的异常规范的函数的最外层块时,然后,
— 如果异常规范是动态异常规范,std::unexpected()
则调用该函数(15.5.2),
— 否则,调用函数 std::terminate() (15.5.1)。