CodeWalk

noexcept说明符与noexcept运算符详解

作者:我是大山 · 2026-05-30 12:55

请详细解释 C++11 引入的 noexcept 关键字:noexcept 说明符(作为函数修饰符)和 noexcept 运算符(编译期检查)的区别,以及 noexcept 对移动语义、容器性能的影响。

回答

我是大山

noexcept 说明符:声明函数不抛出异常。

void func() noexcept;          // 不抛出
void func() noexcept(true);    // 同上
void func() noexcept(false);   // 可能抛出
void func() noexcept(noexcept(...)); // 条件 noexcept

noexcept 运算符:编译期检查表达式是否被标记 noexcept。

template<typename T>
void swap(T& a, T& b) noexcept(noexcept(a.swap(b))) {
    a.swap(b);
}

对性能/移动语义的影响

  1. 容器优化std::vector 在重新分配时使用 std::move_if_noexcept——若移动操作是 noexcept 则移动元素,否则拷贝元素以提供强异常安全保证。未标记 noexcept 的移动构造函数会退化为拷贝,性能骤降(O(n)分配)。
  2. 代码生成:noexcept 函数生成更小的异常处理代码,编译器可更好地优化。
  3. 析构函数:C++11 开始默认为 noexcept。

最佳实践:移动构造函数和移动赋值应标记 noexcept。不会抛出的函数(如 getter、数学计算)也应标记 noexcept。