0

0

C++中的noexcept关键字有什么作用?C++异常安全规范详解【现代C++】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-06 11:21:08

|

126人浏览过

|

来源于php中文网

原创

noexcept是C++11引入的关键字,用于声明函数不抛异常,违反承诺将调用std::terminate;它影响编译器优化、标准库行为(如移动操作选择)、函数类型签名,并支持编译期异常检查。

c++中的noexcept关键字有什么作用?c++异常安全规范详解【现代c++】

noexcept 是 C++11 引入的关键字,用来显式声明一个函数**不会抛出任何异常**。它既是编译器的承诺,也是调用者的契约——一旦标记为 noexcept,函数体内若意外抛出异常(且未被捕获),程序将立即调用 std::terminate() 终止执行,而不是尝试展开。

noexcept 的核心作用:优化与安全边界

它不只是“说明不抛异常”,更直接影响编译器行为和标准库决策:

  • 启用移动操作的强保证:例如 std::vector::resize() 在重新分配内存时,若元素类型的移动构造函数是 noexcept,就会优先选择移动而非复制,显著提升性能;否则可能退化为复制以维持异常安全。
  • 影响函数类型签名void f() noexceptvoid f() 是两种不同的函数类型,不能相互赋值或重载(除非仅 noexcept 性质不同,C++17 起允许这种重载)。
  • 支持 noexcept 运算符判断:可用 noexcept(expr) 在编译期检查某表达式是否不抛异常,常用于模板 SFINAE 或 constexpr if 分支。

noexcept 的两种写法:简单声明 vs. 条件表达式

基本形式:void func() noexcept; 表示硬性承诺不抛异常。

更灵活的是带条件表达式的写法:void func() noexcept(noexcept(other_func()));

立即学习C++免费学习笔记(深入)”;

WPS灵犀
WPS灵犀

WPS灵犀是WPS推出的一款AI智能办公和学习助手

下载
  • 右边的 noexcept(...) 是运算符,返回 bool 编译期常量。
  • 整个声明表示:“本函数是否 noexcept,取决于 other_func() 是否 noexcept”。这是实现“异常中立”(exception-neutral)接口的关键技巧。
  • 常见于模板函数,如自定义容器的移动构造:MyContainer(MyContainer&& rhs) noexcept(noexcept(std::declval().move()))

noexcept 不是万能的:常见误区

它不提供运行时保护,也不自动让函数变安全:

  • noexcept 函数仍可调用会抛异常的函数——只要你在内部捕获了它们;否则直接终止程序。
  • 析构函数默认是 noexcept(true)(C++11 起),所以务必确保析构中不抛异常,或显式写成 ~T() noexcept(false)(极少需要)。
  • 不要为了“看起来高效”盲目加 noexcept。违反承诺的代价是静默崩溃(std::terminate),比异常更难调试。

异常安全的三个等级,noexcept 对应最强一级

C++ 社区通常把异常安全分为三类:

  • 基本保证:失败后对象仍处于有效但未指定状态(如部分插入后容器仍可用)。
  • 强烈保证:失败后对象状态完全回滚,如同操作从未发生(常见于 copy-and-swap)。
  • 不抛保证(noexcept):根本不会失败,也不抛异常——这是最高级的异常安全,也是唯一能被编译器和标准库信任并据此优化的级别。

比如 std::swapstd::unique_ptr 的移动操作都要求 noexcept,否则容器在异常场景下无法保证强安全。

基本上就这些。noexcept 不复杂但容易忽略,关键是把它当作接口契约来设计,而不是事后补的性能标签。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1458

2023.10.24

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1458

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

227

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

85

2025.10.17

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

719

2023.08.22

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

174

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

94

2025.11.27

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1004

2023.10.19

PPT动态图表制作教程大全
PPT动态图表制作教程大全

本专题整合了PPT动态图表制作相关教程,阅读专题下面的文章了解更多详细内容。

13

2026.01.07

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 0.9万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号