C++标准未提供std::get_terminate函数,仅定义了std::set_terminate;调用std::set_terminate返回前一个处理函数,这是唯一获取旧handler的方式。

你不能用 std::get_terminate 获取当前的终止处理函数 —— 这个函数根本不存在。C++ 标准库中没有 std::get_terminate,这是常见误解,源于把 std::set_terminate 和类似 C 的 get* 惯例混淆了。
为什么找不到 std::get_terminate?
C++ 标准只定义了 std::set_terminate,用于安装自定义终止处理函数;但**没有提供对应的获取接口**。标准明确要求实现“记住”当前的 terminate handler,但不暴露读取它的途径。
- 调用
std::set_terminate会返回上一个 handler(类型为std::terminate_handler),这是唯一可间接“获取”的方式 - 如果你没保存过返回值,就无法还原或检查当前 handler
- 试图搜索或声明
std::get_terminate会导致编译错误:error: 'get_terminate' is not a member of 'std'
如何安全地替换并保留原有 terminate handler?
典型做法是在调用 std::set_terminate 时捕获其返回值,即旧 handler。这既是“获取”的等效操作,也是恢复的唯一依据。
std::terminate_handler old_handler = std::set_terminate([]() {
std::cerr << "Custom terminate called\n";
// 注意:这里通常要手动 abort() 或 _Exit(),否则行为未定义
std::abort();
});
// 后续想恢复?
std::set_terminate(old_handler);
- 必须在自定义 handler 内显式调用
std::abort()、_Exit()或std::quick_exit(),否则程序行为未定义 -
old_handler可能是nullptr(如果之前从未设置过),调用前应判空 - 该 handler 是全局状态,多线程下需注意设置时机(通常应在 main 开头或静态初始化阶段)
terminate handler 被触发的常见场景
它不是只在 throw 时起作用,而是在异常机制彻底失效时兜底:
立即学习“C++免费学习笔记(深入)”;
- 析构函数中抛出异常(且该异常未被栈展开过程捕获)
-
std::terminate()被直接调用 - 异常传播到
main()之外(如线程函数退出时仍有未捕获异常) - 异常规范(C++17 已移除
throw(),但noexcept违反仍会调用std::terminate)
真正难处理的不是“怎么设”,而是 handler 内能安全做什么——此时栈已不可靠,new、cout、锁、虚函数调用都可能崩溃。最稳妥的操作只有写入文件描述符(如 write(2, ...))、调用 abort() 或 _Exit()。











