深入使用noexcept

news2025/1/12 9:50:34

深入使用noexcept

    • 简介
      • 好处
      • 坏处
    • 适用场景
    • 不适用场景
    • 实验结果
    • 总结
    • 参考资料

简介

noexcept是C++11引入的,表明函数是否会抛出异常。正确使用它可以优化性能,错误使用则会带来麻烦。

noexcept使用语法有两种:

  1. noexcpet
  2. noexcept(expression)

第二种使用方式允许用表达式决定是否noexcept起效果,当expression的值为true的时候起效果,否则不起效。expression是编译时求值,一切都是在编译时决定。

好处

如果一个函数标注成noexcept

  • 可以选择移动构造函数 / 移动赋值运算符;
  • 编译器就不用生成异常处理代码了,因此可以优化编译。

坏处

如果noexcept的函数执行时出了异常,包括所调用的函数抛出的异常,程序会马上terminate,即使套上try...catch也仍旧会terminate。并且编译器不会帮你检查这样的风险。

适用场景

在需要决定是调用移动构造函数(或者移动赋值运算符)还是复制构造函数(或者复制赋值运算符)时,noexcept会影响决定。因为移动语法会“破坏”原来的源对象的内容,造成无法在出现异常情况下恢复状态。因此只有移动构造函数(或者移动赋值运算符)标明为noexcept时,才能在这种情况下使用移动构造函数(或者移动赋值运算符)替代复制构造函数(或者复制赋值运算符)。

一个例子就是STL库中的vector的扩容,扩容涉及到是复制对象还是移动对象的问题,就是上述的问题。当对象的移动构造函数可能会抛出异常的时候,vector是”不敢“在这个场景下调用的,因为出了异常无法原恢复状态。

详细逻辑如下:

  1. 当使用复制构造时,抛出异常时只要把已复制的对象销毁,新分配的内存释放,一切还能恢复到跟以前一样;
  2. 当使用移动构造时,容器中的原来的元素的状态已经被移动构造破坏了,无法恢复到跟以前一样。

以下是测验代码:

class A {
public:
    A() { std::cout << "constructor" << std::endl; }
    A(const A& a) { std::cout << "copy constructor" << std::endl; }
    A(const A&& a) noexcept { std::cout << "move constructor" << std::endl; } // 有noconcept时,扩容时用移动构造
    // A(const A&& a) { std::cout << "move constructor" << std::endl; }  // 去掉noconcept时,扩容时用拷贝构造
};

int main() {
    std::vector<A> v;
    v.reserve(1);
    for (int i = 0; i < 10; i++) {
        A a; // 构造一个A类的实例。
        v.push_back(a); // 添加进容器时会调用一次复制构造,如果容量不够则会扩容,这时候会选择复制构造还是移动构造。
    }

    return 0;
}

不适用场景

其他情况均不太适合使用。因为:

  1. 编译器不会帮你做检查,假如一个标注noexcept的函数调用未标注noexcept的函数,是可以顺利编译的。但是未标注nonexcept的函数是不保证不抛异常的。
  2. 一个函数加上noexcept之后就可能很难移除,因为其他代码可能会直接或间接引用到它,且假设不会有异常;
  3. 如果一个标注了noexcept的函数自己或者调用的函数(直接或间接)抛出异常,直接终止,非常简单粗暴。

因此出了几个有限的适用场景外,其他情况下不要用noexcept

实验结果

以下图表是来自于 C++ noexcept and move constructors effect on performance in STL Containers — TRYING TO FIND THE OBVIOUS (hlsl.co.uk) 这篇博客的实验结果。
在这里插入图片描述
根据实验结果,性能提升了两倍!

总结

虽然noexcept会在某些情况下提升性能,但是由于它的危险性,包括发生异常直接终止程序且编译器不会帮你检查,除了以下情况下都不建议使用。

  1. 移动构造函数
  2. 移动赋值运算符
  3. 析构函数
  4. 简单函数

1、2 已经在前面说过了,不再赘述。对于3、4,析构函数本身不应该抛异常,简单函数一般不会发生异常,因此可以放心标注noexcept

参考资料

  1. c++ 从vector扩容看noexcept应用场景 - 知乎 (zhihu.com)

  2. C++ noexcept and move constructors effect on performance in STL Containers — TRYING TO FIND THE OBVIOUS (hlsl.co.uk)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/166748.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何提高系统稳定性?

1、系统稳定性的评判标准 在开始谈稳定性保障之前&#xff0c;我们先来聊聊业内经常提及的一个词SLA&#xff01;业内喜欢用SLA &#xff08;服务等级协议&#xff0c;全称&#xff1a;service level agreement&#xff09;来衡量系统的稳定性&#xff0c;对互联网公司来说&am…

测试开发知识总结(一)

本文内容顺序&#xff1a;测试基础理论、测试岗经常被问到的场景题、智力题、测试岗高频算法题、数据库、Linux知识点。常用自动化测试工具1、Appium官网&#xff1a;http://appium.ioAppUI自动化测试Appium 是一个移动端自动化测试开源工具&#xff0c;支持iOS 和Android 平台…

为什么很少拿神经网络来直接做滤波器呢?

其实无论是IIR&#xff08;RNN&#xff09;还是FIR(CNN)滤波器都可以看成一个简单神经网络&#xff0c;而且有严格的推理&#xff0c;可解释性比神经网络强多了&#xff0c;而已易于工程实现&#xff0c;因此在工程中大量应用。你说的含色噪声和其他乱七八糟的噪声难以滤除时&a…

ROS | Realsense中的IMU解算orientation

文章目录概述一、定义介绍二、操作教程(一)、下载并编译imu_tools功能包1.创建工作空间并初始化2.下载imu_tools并编译(二)、修改配置1.修改imu_tools源码2.修改launch文件3.启动解算概述 本文详细介绍了如何使用ROS自带的工具解算6轴IMU&#xff0c;获取其位姿。 一、定义介绍…

mybatis之动态SQL常见标签的使用

引入where标签的原因&#xff1a; 在上篇文章使用if语句的查询中&#xff0c;我们在SQL语句后面都写入了where 11&#xff0c;以保证每次都能够查询出结果&#xff0c;但这种方法并不是最合理的&#xff0c;假设我们现在将where后面的11去掉&#xff1a; 如下所示&#xff1a…

上午摆摊,下午写代码,35岁程序员的双面人生超爽!

最近看到一个程序员发帖分享自己的工作&#xff1a;白天出摊卖馄饨&#xff0c;下午在家为海外公司全职远程工作。“年入百万是可以的&#xff0c;并且我老家是三线城市&#xff0c;没有房租、通勤费用&#xff0c;性价比还是很高的。” 对比在大城市天天996的程序员&#xff0…

【JavaEE】多线程之线程安全(synchronized篇),死锁问题

目录 线程安全问题 观察线程不安全 线程安全问题的原因 从原子性入手解决线程安全问题 ——synchronized synchronized的使用方法 synchronized的互斥性和可重入性 死锁 死锁的三个典型情况 死锁的四个必要条件 破除死锁 线程安全问题 在前面的章节中&#xff0c…

Wav2Vec HuBert 自监督语音识别模型

文章目录Wav2Vec: Unsupervised pre-training for speech recognitionabstractmethodwav2vec 2.0: A Framework for Self-Supervised Learning of Speech RepresentationsabstractintroductionmethodMODEL arch损失函数finetuneexprimentHuBERT: Self-Supervised Speech Repres…

商品期货跨期套利实战笔记

合约对&#xff1a;IC2301&IC2302 价差计算 前-后&#xff08;6082-6079.8&#xff09; 做多价差开仓&#xff08;预期价差变大&#xff09; 买2301&#xff08;前&#xff09; 卖2302&#xff08;后&#xff09; 做空价差开仓&#xff08;预期价差变小&#xff09;&…

【Java|golang】1813. 句子相似性 III

一个句子是由一些单词与它们之间的单个空格组成&#xff0c;且句子的开头和结尾没有多余空格。比方说&#xff0c;“Hello World” &#xff0c;“HELLO” &#xff0c;“hello world hello world” 都是句子。每个单词都 只 包含大写和小写英文字母。 如果两个句子 sentence1…

react hooks组件间的传值方式(使用ts),子孙传值给祖先组件

父子组件传值参考&#xff1a;react hooks组件传值父传子很简单&#xff0c;只要父组件传参&#xff0c;子组件写好interface childProps和props去接收即可子传父稍复杂父组件写一个回调函数&#xff1a;changeTaskState{(id: any) > { changeTaskStateByID(id) }}当然这个 …

图自监督表征

1、综述 数据挖掘领域大师俞士纶团队新作&#xff1a;最新图自监督学习综述图自监督学习综述&#xff1a;Graph Self-Supervised Learning A Survey图自监督学习&#xff08;Graph Self-supervised Learning&#xff09;最新综述Github代码汇总图自监督学习在腾讯Angel Graph中…

基础数学(二)两数之和 三数之和

目录 两数之和_牛客题霸_牛客网 三数之和_牛客题霸_牛客网 两数之和_牛客题霸_牛客网 给出一个整型数组 numbers 和一个目标值 target&#xff0c;请在数组中找出两个加起来等于目标值的数的下标&#xff0c;返回的下标按升序排列。 &#xff08;注&#xff1a;返回的数组下标从…

从0到1完成一个Node后端(express)项目(四、路由、模块化、中间件、跨域)

往期 从0到1完成一个Node后端&#xff08;express&#xff09;项目&#xff08;一、初始化项目、安装nodemon&#xff09; 从0到1完成一个Node后端&#xff08;express&#xff09;项目&#xff08;二、下载数据库、navicat、express连接数据库&#xff09; 从0到1完成一个Nod…

分页查询数据重复的问题 (分页时数据库插入数据导致)

参考&#xff1a;https://blog.csdn.net/desongzhang/article/details/124941189参考之后 自己遇到的坑解决办法一、问题描述分页时&#xff0c;同时在数据库中添加数据&#xff0c;导致第n页和第n1页有部分数据重复(重复条数和查询分页时的添加的数据量有关)二、解决办法分页的…

商业智能 BI 跟业务系统的思维差异,跨越和提升

各行业都已开始进入数据时代&#xff0c;但很多企业还是分不清商业智能 BI 跟一般的业务信息化系统定位、用户、思维层面上的差异。 在企业的 IT 信息化规划中&#xff0c;基础的业务系统建设一定是走在前面的&#xff0c;有了这些系统基础&#xff0c;才会有数据的积累&#…

SH-PEG-Silane巯基-聚乙二醇-硅烷试剂简介Silane-PEG-SH

SH-PEG-Silane巯基-聚乙二醇-硅烷 外观&#xff1a;固体或液体&#xff0c;取决于分子量大小。 PEG可选分子量: 1000,2000,3400&#xff0c;5000&#xff0c;10000 溶剂: 溶于DMSO,DMF,DCM&#xff0c;溶于水。 纯度&#xff1a;>95% 保存&#xff1a;-20℃&#xff0c…

目标检测模型设计准则 | YOLOv7参考的ELAN模型解读,YOLO系列模型思想的设计源头

转载&#xff1a;https://mp.weixin.qq.com/s/5SjQvRqRct6ClpE2eEcdkw设计高效、高质量的表达性网络架构一直是深度学习领域最重要的研究课题。当今的大多数网络设计策略都集中于如何集成从不同层提取的特征&#xff0c;以及如何设计计算单元来有效地提取这些特征&#xff0c;从…

Ubuntu22.04 设置静态IP

1.查看网卡名称及IP ip addr 网卡名称&#xff1a;ens33 IP:192.168.44.130 2.修改配置文件 在 /etc/netplan/ 目录下找到配置文件 *.yaml &#xff0c;修改为 network:version: 2#renderer: NetworkManagerethernets:ens33:addresses: [192.168.44.130/24]dhcp4: nooptio…

Chrome扩展程序(插件),用你开发的脚本在浏览器上随心所欲

Chrome扩展程序&#xff08;插件&#xff09;&#xff0c;用你开发的脚本在浏览器上随心所欲Chrome插件的文件结构Hello_World编写利用JavaScript实现Hello Everything灵活运用浏览器的存储storageoptions_Page基本用法电脑发通知 - Notifications的应用普通界面右键菜单 - con…