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)
(constexpr 自 C++26)
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(); 首先创建一个保护对象,并在其构造函数中记录未捕获异常的数量。输出由保护对象的析构函数执行,除非 foo() 抛出异常(在这种情况下,析构函数中的未捕获异常数量大于构造函数观察到的数量)。

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

宏 值 标准 特性 (C++17)
__cpp_lib_uncaught_exceptions 201411L (C++26) std::uncaught_exceptions
__cpp_lib_constexpr_exceptions 202411L 用于异常类型 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++ 标准。

DR

应用于 已发布行为 正确行为 LWG 70
C++98 的异常规范缺失uncaught_exception()指定为 (void)throw()

参阅

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

外部链接

1.  GOTW issue 47: Uncaught Exceptions
2.  关于 std::uncaught_exceptions 的理由 (N4125)