C++11 的 noexcept 是替代 C++98 废弃异常说明的核心特性,作为函数接口的关键组成部分,仅当确定函数永远不会抛出异常时声明;其核心价值是让编译器生成更高效的目标代码,同时为调用者 / STL 提供明确的异常安全承诺,且不可为了加 noexcept 扭曲函数实现,大多数函数因'异常中立'无需声明。
noexcept 的核心价值
性能层面:编译器最大化优化代码
- 逻辑:
noexcept承诺'函数异常传播时可直接终止程序',编译器无需保证调用栈完整展开、局部对象按构造反序析构,因此可剔除冗余代码,生成更精简高效的机器码; - 对比差异:
noexcept函数的优化度远高于 C++98 的throw()或无异常声明的函数(后两者需预留栈展开的冗余代码);
// noexcept 函数:编译器无冗余准备,极致优化
void moveWidget(Widget&& w) noexcept {
// 无栈展开、析构顺序记录的冗余代码,机器码更精简
}
// throw() 函数:需预留栈展开准备,优化有限(C++17 已废弃)
void moveWidget(Widget&& w) throw() {
// 含局部对象析构顺序记录、栈可展开维护的冗余代码
}
// 无声明函数:默认按'可能抛异常'处理,优化空间极小
void moveWidget(Widget&& w) {
// 同 throw(),冗余代码多,执行效率低
}
语义层面:作为接口承诺,支撑 STL 核心逻辑
- 逻辑:
noexcept是函数接口的关键属性(与const同等重要),调用者 / STL 会依赖该承诺判断是否安全使用高性能逻辑; - 支撑场景:
- 移动操作(构造 / 赋值):STL 容器仅当移动操作
noexcept时,才会用'移动'替代'拷贝'(避免移动抛异常破坏异常安全);
// 移动构造加 noexcept:STL 容器优先用移动(高效且安全)
class Widget {
public:
Widget(Widget&& other) noexcept {
// 转移资源,无异常风险
}
};
std::vector<Widget> vec;
Widget w;
vec.(std::(w));

