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()

使用 noexcept 我们需要知道什么?的更多相关文章

  1. C++11异常处理 noexcept

    1.简介 在C语言中,如果程序的运行出现异常.错误,我们想提供方案处理这些异常时,我们面临许多问题,如: (1)C语言没有提供统一(标准)的方式来处理错误: (2)无法保证错误会被正确的处理: (3) ...

  2. C++11 带来的新特性 (3)—— 关键字noexcept

    1 关键字noexcept 从C++11开始,我们能看到很多代码当中都有关键字noexcept.比如下面就是std::initializer_list的默认构造函数,其中使用了noexcept. co ...

  3. 为什么移动构造要使用noexcept

    vector::push_back操作,保证了如果过程中出现异常,vector不会发生变化. push_back过程中,可能会因为已有内存空间不够,申请新的内存,同时把原内存中已有的元素,放到新申请的 ...

  4. Item 14: 如果函数不会抛出异常就把它们声明为noexcept

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 在C++98中,异常规范(exception specificat ...

  5. c++11 noexcept修饰符

    c++11 noexcept修饰符 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> ...

  6. noexcept(c++11)

    1.概念 1)c++中的异常处理是在运行时而不是编译时检测的,为了实现运行时检测,编译器可能会创建额外的异常处理代码,然而这会妨碍程序优化 2)noexcept说明符:若修饰函数(紧跟在参数列表后面) ...

  7. C++2.0新特性(三)——<=default,=delete、alias(别名)、noexcept、override、final、以及和const对比>

    一.=default,=delete 1.首先我们要回顾一下类默认函数的概念: C++中,当我们设计与编写一个类时,若不显著申明,则类会默认为我们提供如下几个函数: (1)构造函数(A()).(2)析 ...

  8. c++ 从vector扩容看noexcept应用场景

    c++11提供了关键字noexcept,用来指明某个函数无法--或不打算--抛出异常: void foo() noexcept; // a function specified as will nev ...

  9. C++11 noexcept 关键字用法学习

    最近学习和写了一个 mint 的板子 ,其中用到了 noexcept 关键字,对这个关键字不太熟悉,便学习一下刘毅学长的文章. C++98 中的异常规范(Exception Specification ...

随机推荐

  1. C++把数字排序

    C++把数字排序 描述 思路 代码 描述 如题,详细如下: 输入不超过1024个数字,以特殊数字结尾,如(-999),把数字从小到大排序. 思路 目前,我们有两种思路可以写: 1是 在输入的时候,排序 ...

  2. 切换用户后whoami打印用户的问题

    问题: 为何第二个whoami打印的还是root? root@localhost /]# [root@localhost /]# [root@localhost /]# more test.sh #! ...

  3. python中环境变量的使用

    前言 之前就经常用,今天来凑个篇数. 在开发的过程中,我们经常会将代码中某些可能更改的,比如redis地址,数据库地址,限流阈值等参数写活来提高灵活性, 传统的方式可能是写在配置文件中,比如 xml ...

  4. C++题目东华

    1. 定义一个点类Point,其有两个double型的私有数据成员x和y.此外还包含以下公有成员函数: (1)构造函数,给点初始化: (2)setPoint函数,设置点坐标值: (3)distance ...

  5. Netty与NIO

    初识Netty Netty是由JBoss提供的一个Java的开源框架,是GitHub上的独立项目. Netty是一个异步的,基于事件驱动的网络应用框架,用于快速开发高性能.高可靠的网络IO程序. Ne ...

  6. Linux学习笔记 | 常见错误之无法获得锁

    问题: 当运行sudo apt-get install/update/其他命令时,会出现如下提示: E: 无法获得锁 /var/lib/dpkg/lock-frontend - open (11: 资 ...

  7. JavaScript入门-对象

    js对象 本篇主要介绍js里如何创建对象,以及for循环访问对象的成员... 什么是对象? 对象,并不是中文里有男女朋友意思,它是从英文里翻译来的,英文叫[Object],目标,物体,物品的意思. 在 ...

  8. 【Oracle】从删除的recyclebin中查看并恢复数据

    如果数据库中用了drop删除表,后面没有加上purge的话,会出现在oracle的回收机制中 dba_recyclebin可以查看当前删除的都是哪些 这个只是部分截图,可以看到删除的对象是什么,删除的 ...

  9. Flink源码剖析:Jar包任务提交流程

    Flink基于用户程序生成JobGraph,提交到集群进行分布式部署运行.本篇从源码角度讲解一下Flink Jar包是如何被提交到集群的.(本文源码基于Flink 1.11.3) 1 Flink ru ...

  10. 计网Q1:多个方面比较电路交换、报文交换和分组交换的主要优缺点

    网上看到的带佬儿的帖子......膜过来<doge 原文链接: https://blog.csdn.net/njchenyi/article/details/1540657 电路交换: 由于电路 ...