noexcept 关键字

noexcept 是什么?

noexcept 是自 C++11 引入的新特性,指定函数是否可能会引发异常,以下是 noexcept 的标准语法:

noexcept-expression:

    noexcept

    noexcept(** *constant-expression* **)

constant-expression 是一个 bool 类型的常量表达式,是一种异常规范(exception specification),属于C++的语言特性,表示是否会发生异常。

noexcept 等效于 noexcept(true)

noexcept(true) 或者 noexcept 表示函数不会抛出或者传递异常,如果函数发生异常,将调用 std::terminate 立即终止程序。

noexcept(false) or 或者不使用 noexcept (析构函数或释放函数默认声明为 noexcept), 表示函数所有可能的异常都会被抛出.

应该使用 nonexcept 的情形

建议将所有不会抛出异常(包括以后)的函数声明为 noexcept

当函数声明为 noexcept 后,编译器能够在一些不同的上下文环境中产生更加高效的代码。

不应该使用 nonexcept 的情形

函数可以标记为 noexcept 当且仅当内部调用的所有函数也都直接或者间接的标记为 noexcept 或者 const

编译器没有义务检查所有层级代码是否会抛出异常到 noexcept 函数。

如果标记了 noexcept 的函数确实抛出了异常,那么std::terminate将会被立即调用,并且不能保证函数内部的对象能够被析构。

比起优化,正确性更为重要。

当你在最开始声明一个函数为 noexcept, 而后又反悔想要去掉 noexcept 标记,那么你将会影响到调用端的代码。

示例

下面的函数被标记为有条件的 noexcept:函数是否为 noexcept 取决于 noexcept 的子句表达式是否为 noexcept

例如,有两个包含 Widget 对象的数组,交换两个数组的函数是否为 noexcept 取决于 交换两个数组中元素的函数是否为 noexcept,即,交换两个 Widget 对象是否为 noexcept

因此 Widget 对象 swap 的实现决定了 Widget 数组的交换函数是否为 noexcept

同样地,包含 Widgets 的 std::pair 对象的交换函数是否应该为 noexcept 取决于交换两个 Widget 对象是否为 noexcept

上层的数据结构操作可以为 noexcept 仅当下层的数据结构操作为 noexcept。这就促使你,只要允许,就尽可能地提供 noexcept 的函数。

template <class T, size_t N>
void swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b))); template <class T1, class T2>
struct pair {

void swap(pair& p) noexcept(noexcept(swap(first, p.first)) && noexcept(swap(second, p.second)));

};

总结

  • noexcept 是函数接口的一部分,这意味着调用者会依赖它。
  • noexcept 函数可优化性要高于 non-noexcept 函数。
  • noexcept 用在数据移动,交换,内存释放函数,析构函数中会更有价值。
  • 大多数函数本质上是属于 non-noexcept 的。

扩展

在 C++17 之前还有一种异常规范 (dynamic exception pecification) throw(optional_type_list)

C++17 之后 throw(optional_type_list) 已被移除(除了 throw()),throw() 等同于 noexcept

应该避免使用 throw(optional_type_list) 或者 throw()

最新文章

  1. 如何一步一步用DDD设计一个电商网站(十)—— 一个完整的购物车
  2. C#检验参数合法性公用方法
  3. C#单例模式的多种写法
  4. iOS中修改头部tabBarButton 默认按钮的颜色和默认字体颜色
  5. Android 2.x中使用actionbar - Actionbarsherlock
  6. 利用JBoss漏洞拿webshell方法
  7. JQuery的$(document).ready(function(){})与JS的window.onload 的各自优势!
  8. 利用智能手机(Android)追踪一块磁铁(三)
  9. js-学习方法之3
  10. bzoj3048[Usaco2013 Jan]Cow Lineup 尺取法
  11. Oracle--配置并保存PL/SQL Developer界面
  12. nodejs接收get参数和post参数
  13. df=df.reset_index(drop=True)
  14. iis8使用url2.0模块实现http跳转到https
  15. Laravel之路由 Route::get/post/any、路由参数、过滤器、命名、子域名、前缀、与模型绑定、抛出 404 错误、控制器
  16. python 全栈开发,Day139(websocket原理,flask之请求上下文)
  17. tensorflow学习2-线性拟合和神经网路拟合
  18. odoo开发笔记--模型字段compute用法
  19. Windows Phone SDK 8/8.1 官方下载
  20. charles手机抓包配置-1

热门文章

  1. 如何使用蓝湖设计稿同时适配PC及移动端
  2. C++题目东华
  3. LeetCode222 判断是否为完全二叉树并求节点个数
  4. Linux 安装JDK配置环境(rpm安装和压缩版安装)
  5. 【Linux】salt的cmd.script命令介绍
  6. 洛谷P3275 [SCOI2011]糖果(差分约束)
  7. python之格式化字符串速记整理
  8. 强制删除 Terminating 状态的pod
  9. STP 根桥、根端口、指定端口是如何选举的
  10. jmeter的线程数,并发用户数,TPS,RPS 关系解说