std::uncaught_exception, std::uncaught_exceptions
来自 cppreference.cn
                    
                                        
                    
                    
                                                            
                    | 定义于头文件  <exception> | ||
| (1) | ||
| bool uncaught_exception() throw(); | (C++11 前) | |
| bool uncaught_exception() noexcept; | (C++11 起) (C++17 中已弃用) (C++20 中移除) | |
| int uncaught_exceptions() noexcept; | (2) | (C++17 起) (C++26 起为 constexpr) | 
1) 检测当前线程是否有活跃的异常对象,即异常已被抛出或重新抛出但尚未进入匹配的 catch 子句,std::terminate 或 std::unexpected。换句话说,
std::uncaught_exception 检测是否正在进行栈展开。2) 检测当前线程中有多少异常已被抛出或重新抛出但尚未进入其匹配的 catch 子句。
有时即使在 std::uncaught_exception() == true(直到 C++17) std::uncaught_exceptions() > 0(自 C++17 起) 时抛出异常也是安全的。例如,如果栈展开导致一个对象被析构,该对象的析构函数可以运行抛出异常的代码,只要该异常在逃离析构函数之前被某个 catch 块捕获。
| 目录 | 
[编辑] 参数
(无)
[编辑] 返回值
1) 如果当前线程正在进行栈展开,则为 true,否则为 false。
2) 当前线程中未捕获异常对象的数量。
[编辑] 注意
一个使用返回 int 值的 uncaught_exceptions 的例子是 boost.log 库:表达式 BOOST_LOG(logger) << foo(); 首先创建一个 guard 对象并在其构造函数中记录未捕获异常的数量。输出由 guard 对象的析构函数执行,除非 foo() 抛出异常(在这种情况下,析构函数中未捕获异常的数量将大于构造函数中观察到的数量)。
LFTS v3 中的 std::experimental::scope_fail 和 std::experimental::scope_success 依赖于 uncaught_exceptions 的功能,因为它们的析构函数需要根据是否在栈展开期间调用而执行不同的操作。
| 特性测试宏 | 值 | 标准 | 特性 | 
|---|---|---|---|
| __cpp_lib_uncaught_exceptions | 201411L | (C++17) | std::uncaught_exceptions | 
| __cpp_lib_constexpr_exceptions | 202411L | (C++26) | 异常类型的 constexpr | 
[编辑] 示例
运行此代码
#include <exception> #include <iostream> #include <stdexcept> struct Foo { char id{'?'}; int count = std::uncaught_exceptions(); ~Foo() { count == std::uncaught_exceptions() ? std::cout << id << ".~Foo() called normally\n" : std::cout << id << ".~Foo() called during stack unwinding\n"; } }; int main() { Foo f{'f'}; try { Foo g{'g'}; std::cout << "Exception thrown\n"; throw std::runtime_error("test exception"); } catch (const std::exception& e) { std::cout << "Exception caught: " << e.what() << '\n'; } }
可能的输出
Exception thrown g.~Foo() called during stack unwinding Exception caught: test exception f.~Foo() called normally
[编辑] 缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
| 缺陷报告 | 应用于 | 发布时的行为 | 正确的行为 | 
|---|---|---|---|
| LWG 70 | C++98 | uncaught_exception()的异常规范缺失 | 指定为 throw() | 
[编辑] 另请参阅
| 异常处理失败时调用的函数 (函数) | |
| (C++11) | 用于处理异常对象的共享指针类型 (typedef) | 
| (C++11) | 将当前异常捕获到 std::exception_ptr 中 (函数) | 
[编辑] 外部链接
| 1. | GOTW issue 47: 未捕获异常 | 
| 2. | std::uncaught_exceptions的原理 (N4125) | 


