为什么要在unexpected()异常处理函数中主动抛出异常?
std::unexpected处理程序抛异常的作用与传播逻辑 首先澄清一个认知误区:std::unexpected不是全局最后一层异常捕获机制,它是C++98/03版本的动态异常规范的配套机制,仅当函数抛出了自身异常声明(形如void foo() throw(A, B))中未列明的异常类型时,才会被运行时调用。
处理程序内抛异常的意义
这么做的核心目的是让程序有机会从异常违规场景中恢复,而非直接终止,常见用途包括:
- 异常类型适配:将不符合当前函数异常规范的异常,转换为规范允许的类型再抛出,比如把第三方库抛出的未知异常包装成
std::runtime_error,满足规范要求后可以继续走正常异常处理流程 - 后置处理后传递异常:可以在处理程序内先完成日志打印、临时资源释放等操作,再抛出预设的通用异常类型,方便上层业务代码统一捕获处理
处理程序抛出的异常的去向
会根据抛出的异常是否符合触发unexpected的函数的异常规范,分两种情况处理:
- 若新抛出的异常符合规范要求:该异常会替换原有违规异常,沿着调用栈正常向上传播,由上层匹配的
catch块捕获,和普通异常的传播逻辑完全一致 - 若新抛出的异常仍然不符合规范要求:
- 如果当前函数的异常规范中包含
std::bad_exception,运行时会自动将异常替换为std::bad_exception实例,继续向上传播 - 如果异常规范中没有包含
std::bad_exception,运行时会直接调用std::terminate终止程序
- 如果当前函数的异常规范中包含
补充说明:C11已经正式弃用动态异常规范,C17完全移除了该特性,
std::unexpected相关接口也随之被弃用,现在异常说明符仅保留noexcept,违规时直接调用std::terminate终止程序。
内容的提问来源于stack exchange,提问作者Sandeep
相关产品推荐
相关产品推荐

