You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用非std::exception派生类型调用std::promise::set_exception触发terminate的规范查询

关于std::promise传递非std::exception类型异常的行为

先看问题中的代码场景:

#include <iostream>
#include <future>

struct X {}; // 不继承std::exception的类型

int main()
{
    auto ep = std::make_exception_ptr(X{}); // (1)
    std::promise<int> p;
    p.set_exception(ep);
    try {
        p.get_future().get();  // (2)
    } catch(const std::exception& exc) {
        std::cout << exc.what();
    }
    return 0;
}

当X不继承std::exception时,调用std::future::get()会触发std::terminate(),这一行为完全符合C++标准的规定:

  • std::future::get()的异常抛出规则
    根据C标准(以C20为例,[futures.unique_future.get]条款),当std::promise通过set_exception设置了异常指针后,调用std::future::get()会重新抛出该异常指针指向的异常对象。

  • 未捕获异常的处理规则
    标准中[except.terminate]条款明确:如果抛出的异常没有找到任何匹配的catch块,程序会调用std::terminate()终止执行。

在上述代码中,std::future::get()抛出的是X类型的异常,但catch块仅捕获const std::exception&类型的异常,没有匹配的处理逻辑,因此触发std::terminate()是必然结果。

需要注意的是,std::make_exception_ptr本身允许封装任意类型的异常对象,但这并不改变C++异常处理的核心规则——未被捕获的异常一定会导致程序终止。

内容的提问来源于stack exchange,提问作者user1832484

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 04:45:29