《Effective Modern C++》学习笔记之条款十四:只要函数不会发射异常,就为其加上noexcept声明

《Effective Modern C++》学习笔记之条款十四:只要函数不会发射异常,就为其加上noexcept声明

首先,如果知道一个函数不可能抛出异常,则应该将其声明为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。

要点速记

  • noexcept声明是函数接口的组成部分,这意味着调用方可能对其有依赖
  • 相对于不带nocept声明的函数,带nocept声明的函数有更多机会得到优化
  • noexcept性质对移动操作、swap、内存释放函数、析构函数最有价值
  • 大多数函数都是异常中立的,不具备noexcept性质

 

上一篇:Concurrency-with-Modern-Cpp学习笔记 - 并发架构


下一篇:Python机器学习(五十九)SciPy 输入输出