首先,如果知道一个函数不可能抛出异常,则应该将其声明为noexcept,以提高代码的运行效率,但是如果函数违反声明而抛出了异常,将导致程序直接中止。

在C++98和C++11中都可以声明一个函数不会抛出异常,代码如下:

int f(int x) throw(); //f不会抛出异常,C++98风格
int f(int x) noexcept; //f不会抛出异常,C++11风格

而使用noexcept而非throw()好处有一下几个原因:

  1. 声明为nocept,优化器会对函数做最大值的优化,包括将执行器栈保持在可开解状态。

  2. C++11新增了移动语义,所以STL标准库也做了一次大的性能调整,即在原先赋值操作地方,将采用"能移动则移动,必须复制才复制"策略。而能否移动的一个关键点就是STL函数是否声明了noexcept。而STL函数是否声明noexcept,取决于STL容器所含自定义对象对应的函数是否声明了noexcept。例如:如果自定义对象的移动拷贝函数声明了noexcept,则在对该对象进行push_back后扩张时,将使用移动拷贝而非复制拷贝,又或者对某对象的swap()成员函数声明了noexcept,则容器在调用STL的swap()函数时,将使用移动拷贝。

  3. 默认的,所有内存释放函数(delete函数)或析构函数,无论是用户自定义还是编译器生成,都隐式的声明了noexcept。