C++ noexcept关键字作用 _ 异常规格说明与移动优化【详解】

陌枫君_1840

陌枫君_1840

2026-04-08

656人浏览

原创

noexcept 是向编译器承诺函数绝不会栈展开,违者调用 std::terminate;它决定标准容器是否选用移动而非拷贝操作,需显式声明并确保所有调用均满足该承诺。

c++ noexcept关键字作用 _ 异常规格说明与移动优化【详解】

noexcept 不是用来“声明函数不抛异常”的装饰,而是向编译器发出一个可验证的承诺:该函数在任何情况下都不会退出(即不会 stack-unwind)。一旦违反,程序直接调用 std::terminate —— 不是抛新异常,不是捕获,是立即终止。

noexcept 会影响 move 构造/赋值是否被自动选用

这是最常踩坑的点。标准容器(如 std::vector)在扩容时,若元素类型有 noexcept 移动构造函数,就优先用移动;否则退回到拷贝——哪怕你写了移动函数,只要没加 noexcept,编译器就认为“不安全”,不敢用。

  • std::vector 的 resize、push_back、reserve 等操作依赖此判断
  • 自定义类的移动构造函数必须显式写 T(T&&) noexcept,不能只靠 = default(因为默认生成的版本是否 noexcept 取决于其成员是否都 noexcept)
  • 检查方式:static_assert(std::is_nothrow_move_constructible_v<mytype>);</mytype>

noexcept(expr) 是运行时检测,不是编译时断言

noexcept 后面跟括号时(如 noexcept(sizeof(T) > 4) 或 noexcept(std::is_nothrow_move_constructible_v<t>)</t>),它是个运算符,结果是 bool 常量表达式,用于模板推导或 SFINAE 场景。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • noexcept(func()) 会尝试分析 func 的异常说明,但不执行 func();若 func 未声明异常规格,则为 false
  • 不要误以为 noexcept(ptr->foo()) 能捕获运行时异常——它只是查声明,不是 try/catch
  • 常见误用:noexcept(my_vector.push_back(x)) 返回 false,因为 std::vector::push_back 本身不是 noexcept

noexcept(true) 和 noexcept(false) 的等价写法与陷阱

void f() noexcept 等价于 void f() noexcept(true);void f() noexcept(false) 显式表示可能抛异常(C++11 中曾用 throw(),已弃用)。

  • 空 noexcept 比 noexcept(true) 更常用,但二者语义完全一致
  • noexcept(false) 几乎不用——除非你要在模板中特化控制异常传播行为,且明确需要覆盖默认推导
  • 注意:析构函数默认是 noexcept(true),手动写 ~T() noexcept(false) 是危险操作,可能导致栈展开中途崩溃

真正关键的不是“要不要加 noexcept”,而是“加了之后,所有被调用的函数是否真的满足这个承诺”。一个 noexcept 移动构造函数里调了可能抛异常的 new 或 std::string 操作,就是未定义行为触发点。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

6119

3

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

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

2023.10.24

6004

49

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

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

2023.10.24

6004

49

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

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

2024.02.23

2824

5

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

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

2025.10.17

1732

13

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

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

2023.11.23

636

5

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

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

2025.11.27

351

13

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

5567

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2428

6

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习