Namespaces
Variants

std::uncaught_exception, std::uncaught_exceptions

来自 zh.cppreference.net
定义于头文件 <exception>
bool uncaught_exception() throw();
(1) (至 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) 当前线程中未捕获异常对象的数量。

注释

一个使用返回整型的 uncaught_exceptions 的示例是 boost.log 库:表达式 BOOST_LOG ( logger ) << foo ( ) ; 首先创建一个守卫对象,并在其构造函数中记录未捕获异常的数量。输出由守卫对象的析构函数执行,除非 foo ( ) 抛出异常(此时析构函数中的未捕获异常数量大于构造函数中观察到的数量)。

std::experimental::scope_fail 和 std::experimental::scope_success 在 LFTS v3 中依赖于 uncaught_exceptions 的功能,因为它们的析构函数需要根据是否在栈展开期间被调用来执行不同的操作。

功能测试 宏 值 标准 功能
__cpp_lib_uncaught_exceptions 201411L (C++17) std::uncaught_exceptions
__cpp_lib_constexpr_exceptions 202411L (C++26) constexpr for exception types

示例

#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++标准。

DR 适用范围 发布时的行为 正确行为
LWG 70 C++98 uncaught_exception() 的异常规范缺失 指定为 throw()

参见

td> 用于处理异常对象的共享指针类型
(类型定义)
异常处理失败时调用的函数
(函数)
将当前异常捕获到 std::exception_ptr 中
(函数)

外部链接

1. GOTW 第47期:未捕获异常
2. std::uncaught_exceptions 的设计依据 (N4125)