# C++中的noexcept关键字

# 为什么引入noexcept关键字

noexcept是C++11中添加的一个关键字,用于指定函数是否会抛出异常。

编译器可以使用noexcept信息来对不抛出异常的函数启用某些优化。

noexcept关键字修饰的函数,可以使用noexcept运算符在编译时检查特定表达式是否被声明为抛出任何异常。

noexceptthrow()的改进版本,throw()在C++11中已被弃用。与throw()不同,noexcept不会调用std::unexpected,并且可能会或可能不会展开堆栈。

# 定义与使用示例

声明一个函数会抛出异常:

void func() noexcept;
void func() noexcept(true);

声明一个函数不会抛出异常:

void func();
void func() noexcept(false);

旧版使用throw声明一个函数会不会抛出异常:

void func() throw(); // 不抛出异常

当在声明中有noexcept修饰的函数中抛出异常时,编译时不会报错,但在函数运行时会直接调用terminate终止程序,以确保在noexcept函数中不抛出异常。

void func() noexcept;

void func() noexcept {
    throw std::exception();
}

/**
 * terminate called after throwing an instance of 'std::exception'
 * what():  std::exception
 * Aborted (core dumped)
 */
  • 1)可以函数指针的声明和定义中指定noexcept
  • 2)在typedef和类型别名中不可以出现noexcept
  • 3)noexcept要么出现在函数的所有生命语句和定义语句中,要么一次也不出现
  • 4)类的成员函数中,noexcept需要跟在const以及引用限定符之后,在final、override或虚函数=0之前。
  • 5)函数指针及该指针指向的函数必须具有一致的异常说明。如果一个指针做出了不抛出异常的声明,则该指针将只能指向不抛出异常的函数。
  • 6)如果一个虚函数承诺不会抛出异常,则后续派生出来的衍生类的虚函数也必须做出同样的承诺。反之则不需要。

# 参考