现代 c++ 一:c++11 ~ c++23 新特性汇总

所谓现代 c++,指的是从 c++11 开始的 c++,从 c++11 开始,加入一些比较现代的语言特性和改进了的库实现,使得用 c++ 开发少了很多心智负担,程序也更加健壮,“看起来像一门新语言”。

从 c++11 开始,每 3 年发布一个新版本,到今年(2024)已经有 5 个版本了,分别是 c++11、c++14、c++17、c++20、c++23,这 5 个版本引入了上百个新的语言特性和新的标准库特性。

1. 新特性
1.1 c++11 新特性
c++11 是一个 major 版本,现代 c++ 开天辟地的版本,有特别多新东西。

新的语言特性[1]:

内存模型——一个高效的为现代硬件设计的底层抽象,作为描述并发的基础
auto 和 decltype——避免类型名称的不必要重复
范围 for——对范围的简单顺序遍历
移动语义和右值引用——减少数据拷贝
统一初始化—— 对所有类型都(几乎)完全一致的初始化语法和语义
nullptr——给空指针一个名字
constexpr 函数——在编译期进行求值的函数
用户定义字面量——为用户自定义类型提供字面量支持
原始字符串字面量——不需要转义字符的字面量,主要用在正则表达式中
属性——将任意信息同一个名字关联
lambda 表达式——匿名函数对象
变参模板——可以处理任意个任意类型的参数的模板
模板别名——能够重命名模板并为新名称绑定一些模板参数
noexcept——确保函数不会抛出异常的方法
override 和 final——用于管理大型类层次结构的明确语法
static_assert——编译期断言
long long——更长的整数类型
默认成员初始化器——给数据成员一个默认值,这个默认值可以被构造函数中的初始化所取代
enum class——枚举值带有作用域的强类型枚举
新的标准库特性[1]:

unique_ptr 和 shared_ptr——依赖 RAII 的资源管理指针
内存模型和 atomic 变量
thread、mutex、condition_variable 等——为基本的系统层级的并发提供了类型安全、可移植的支持
future、promise 和 packaged_task,等——稍稍更高级的并发
tuple——匿名的简单复合类型
类型特征(type trait)——类型的可测试属性,用于元编程
正则表达式匹配
随机数——带有许多生成器(引擎)和多种分布
时间——time_point 和 duration
unordered_map 等——哈希表
forward_list——单向链表
array——具有固定常量大小的数组,并且会记住自己的大小
emplace 运算——在容器内直接构建对象,避免拷贝
exception_ptr——允许在线程之间传递异常
1.2 c++14 新特性
c++14 是一个 minor 版本,没什么重要的新特性,主要是在给 c++11 打补丁,为使用者 “带来极大方便”,实现 “对新手更为友好” 这一目标。

新的语言特性[2]:

泛型的lambda
Lambda捕获部分中使用表达式
函数返回类型推导
另一种类型推断:decltype(auto)
放松的constexpr函数限制
变量模板
聚合类成员初始化
二进制字面量: 0b或0B 前缀
数字分位符
deprecated 属性
新的标准库特性[2]:

共享的互斥体和锁: std::shared_timed_mutex
元函数的别名
关联容器中的异构查找
标准自定义字面量
通过类型寻址多元组
较小的标准库特性: std::make_unique, std::is_final 等
1.3 c++17 新特性
c++17 是一个 “中” 版本(它本来应该是一个 major 版本)。

新的语言特性[3]:

保证拷贝省略。
超对齐类型的动态分配。
严格指定运算顺序。
UTF-8 字面量。
十六进制浮点字面量。
折叠表达式。
泛型值模板参数(auto模板参数)。
类模板参数的类型推导。
编译时 if。
带有初始值设定项的选择语句。
constexpr 匿名函数。
inline 变量。
结构化绑定。
新的标准属性:[[maybe_unused]]、[[nodiscard]] 和 [[fallthrough]]。
std::byte 类型。
用底层类型的值来初始化 enum 类型。
一些小的扩展。
新的标准库特性[3]:

文件系统。
并行算法。
数学特殊函数。
string_view。
any。
variant。
optional。
调用任何可以为给定参数集调用的方法:invoke()。
基本字符串转换:to_chars() 和 from_chars()。
多态分配器。
scoped_lock。
一些小的扩展。
1.4 c++20 新特性
c++20 是一个 major 版本,有很重要的更新,“The Big Four”,即四个重要的特性,分别是:模块、概念、协程、和范围。

新的语言特性[3]:

模块
概念
协程
可指定的初始值设定项(C99功能的略微受限版本)
<=>(“宇宙飞船操作符”)三向比较操作符
[*this]按值捕获当前对象
标准属性 [[no_unique address]]、[[likely]] 和 [[unlikely]]
在 constexpr 函数中允许使用更多功能,包括 new、union、try-catch、dynamic_cast 和 typeid
保证编译时求值的 consteval 函数
保证静态(非运行时)初始化的 constinit 变量
using 可用于带作用域的 enum
还有一些小的扩展
新的标准库特性[3]:

范围、视图和管道
printf() 风格的格式化: format() 和 vformat()
日历和时区
span,用于对连续数组进行读写访问
source_location
数学常数,例如 pi 和 1n10e
对 atomic 的许多扩展
等待多个 thread 的方法: barrier 和 latch
特性测试宏
bit cast<>
位操作
更多的标准库函数成为 constexpr
在标准库中更多地使用 <=> 操作符
更多的小扩展
1.5 c++23 新特性
c++23 是一个 minor 版本。

新的语言特性[4]:

新语言功能特性测试宏
显式对象形参,显式对象成员函数(推导 this)
if consteval / if not consteval
多维下标运算符(例如 v[1, 3, 7] = 42;)
static operator()
static operator[]
auto(x):语言中的衰退复制
lambda 表达式上的属性
可选的扩展浮点类型:std::float{16|32|64|128}_t 和 std::bfloat16_t。
(有符号)std::size_t 字面量的字面量后缀 'Z'/'z'。
后缀
#elifdef、#elifndef 与 #warning
通过新属性 [[assume(表达式)]] 进行假设
具名通用字符转义
可移植源文件编码为 UTF-8
行拼合之前修剪空白
新的标准库特性[4]:

新的库功能特性测试宏
新的范围折叠算法
字符串格式化改进
“平铺(flat)”容器适配器:std::flat_map、std::flat_multimap、std::flat_set、std::flat_multiset
std::mdspan
std::generator
std::basic_string::contains, std::basic_string_view::contains
禁止从 nullptr 构造 std::string_view
std::basic_string::resize_and_overwrite
std::optional 的单子式操作:or_else、and_then、transform
栈踪迹(stacktrace)库
新的范围算法
新的范围适配器(视图)
对范围库的修改
对视图的修改
标记不可达代码:std::unreachable
新的词汇类型 std::expected
std::move_only_function
新的带有程序提供的固定大小缓冲区的 I/O 流 std::spanstream
std::byteswap
std::to_underlying
关联容器的异质擦除
2. 编译器支持情况
2.1 按版本区分
c++11 : Compiler support for C++11
c++14 : Compiler support for C++14
c++17 : Compiler support for C++17
c++20 : C++ compiler support
c++23 : C++ compiler support
2.2 按编译器区分
gcc : C++ Standards Support in GCC
clang : C++ Support in Clang
汇总 : cpp/compiler support/vendors
3. 参考
[1] Bjarne Stroustrup. c++11:感觉像是门新语言. Cpp-Club. Available at : https://github.com/Cpp-Club/Cxx_HOPL4_zh/blob/main/04.md, 2023-6-11.

[2] Wikipedia. c++14. Available at: https://zh.wikipedia.org/wiki/c++14.

[3] [美] Bjarne Stroustrup. C++之旅(第3版). pansz. 北京: 电子工业出版社, 2023-10(1).

[4] cppreference. c++23. Available at: https://zh.cppreference.com/w/cpp/23, 2024-3-3.
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.youkuaiyun.com/antsmall/article/details/138680314

现代C++程序设计(原书第2版)》图文并茂,通俗易懂,真正做到寓教于乐,是本难得的C++面向对象设计入门教材。 出版者的话 译者序 前言 第1章 C++概述与软件开发 1.1 什么是C语言和C++ 1.1.1 C和C++历史回顾 1.1.2 C/C++门编译语言 1.1.3 为什么许多程序员都选择C++ 1.2 什么是面向对象 1.2.1 C++程序并不定是面向对象的 1.2.2 个简单的面向对象程序示例 1.2.3 面向对象的软件更有优势 1.3 结构化设计与面向对象设计 1.3.1 ATM——结构化设计 1.3.2 采用面向对象方法的ATM——究竟是谁的任务 1.3.3 汽车维护——结构化设计 1.3.4 采用面向对象方法的汽车维护——究竟是谁的任务 1.4 软件开发技术概述 1.5 问题发现与解决 复习题 第2章 C++的入门知识 2.1 编程基础 2.1.1 算法设计 2.1.2 正确的软件开发步骤 2.2 专业术语及工程创建 2.3 C++程序的般格式 2.3.1 “Hello World!”程序 2.3.2 “How’s the Weather?”程序 2.4 程序的数据及数据类型 2.4.1 C++的数据类型 2.4.2 容器=数据类型,标签=变量名 2.4.3 数据类型修饰符 2.4.4 问题分析:整型数据究竟有多大 2.5 C++中的变量声明 2.5.1 C++的命名规则 2.5.2 在哪里声明变量 2.6 C++中的运算符 2.6.1 计算路程的程序 2.6.2 从键盘输入程序所需数据 2.6.3 赋值运算符 2.6.4 运算符的优先级 2.6.5 数据类型及其存储的值 2.6.6 算术运算符 2.6.7 自增运算符和自减运算符 2.6.8 复合赋值运算符 2.7 #define、const和数据类型转换 2.7.1 #define预处理指令 2.7.2 const修饰符 2.7.3 const比#define好吗 2.7.4 数据类型转换 2.8 关于键盘输入和屏幕输出的更多内容 2.8.1 转义序列 2.8.2 ios格式标记 2.8.3 流的IO控制符 2.9 开始使用类和对象、C++string类 2.10 练习 复习题 第3章 控制语句和循环 3.1 关系运算符和逻辑运算符 3.2 if语句 3.2.1 if-else语句 3.2.2 问题分析:在if语句中使用大括号 3.2.3 if-else if-else语句 3.2.4 低效的编程方法 3.2.5 if-else程序示例 3.2.6 嵌套if-else语句 3.2.7 条件运算符“?” 3.3 switch语句 3.4 循环 3.4.1 括号的用法 3.4.2 无限循环 3.5 for循环 3.5.1 不要改变循环索引 3.5.2 for循环示例 3.6 while循环 3.7 do while循环 3.8 跳转语句 3.8.1 break语句 3.8.2 continue语句 3.9 问题发现与解决 3.9.1 五个常见错误 3.9.2 调试程序 3.10 C++类与vector类 3.11 总结 3.12 练习 复习题 第4章 函数:基础 4.1 C++中的函数 4.1.1 只由个main函数构成的程序 4.1.2 包含多个函数的程序 4.1.3 函数是个好东西 4.1.4 三个重要的问题 4.2 函数:基本格式 4.3 函数的编写要求 4.3.1 你想住在C++旅馆中吗 4.3.2 函数为先 4.3.3 函数声明或函数原型 4.3.4 函数定义、函数标题行与函数体 4.3.5 函数调用 4.3.6 传值调用 4.3.7 问题分析:未声明的标识符 4.4 重载函数 4.5 具有默认输入参数列表的函数 4.6 局部变量、全局变量和静态变量 4.6.1 局部变量 4.6.2 块范围 4.6.3 全局变量 4.6.4 危险的全局变量 4.6.5 问题分析:全局变量y0、y1与cmath 4.6.6 静态变量 4.7 C++stringstream类 4.8 总结 4.9 练习 复习题 第5章 函数二:变量地址、指针以及引用 5.1 数据变量和内存 5.1.1 sizeof运算符 5.1.2 预留内存 5.1.3 计算机内存和十六进制 5.2 取地址运算符& 5.3 指针 5.4 函数、指针以及间接运算符 5.4.1 解决思路 5.4.2 指针和函数 5.4.3 有效处理大型数据 5.5 函数和引用 5.5.1 复习:两种机制 5.5.2 为什么要强调指针的重要性 5.6 queue类 5.7 总结 5.8 练习 复习题 第6章 数组 6.1 使用单个数据变量 6.2 数组基础 6.2.1 数组的索引值从0开始 6.2.2 使用for循环和数组来实现的电话账单程序 6.2.3 数组的声明和初始化 6.2.4 数组越界==严重的问题 6.2.5 vector与数组的比较 6.3 数组和函数 6.3.1 每个数组都有个指针 6.3.2 数组指针 6.3.3 向函数传递数组:最开始的引用调用 6.3.4 利用数组和函数生成随机数并进行排序 6.4 C字符串,也称为字符数组 6.4.1 字符数组的初始化 6.4.2 null字符 6.4.3 C字符串的输入 6.4.4 C++中提供的字符数组函数 6.5 多维数组 6.5.1 二维数组的初始化 6.5.2 嵌套的for循环和二维数组 6.5.3 利用二维数组来实现Bingo游戏 6.6 多维数组和函数 6.6.1 改进的Bingo卡片程序 6.6.2 白雪公主:利用二维数组来存储姓名 6.7 利用数据文件对数组赋值 6.8 总结 6.9 练习 复习题 第7章 类和对象 7.1 我们所了解的类和对象 7.2 编写自己的类 7.2.1 入门实例:自定义日期类 7.2.2 第C++类:Date类 7.2.3 揭开类的生命之谜 7.2.4 set和get函数的作用与VolumeCalc类 7.2.5 PICalculator类 7.3 作为类成员的对象 7.4 类的析构函数 7.5 对象数组 7.6 重载运算符与对象 7.7 指针、引用和类 7.7.1 指针和引用实例 7.7.2 处理日期和时间的程序实例 7.8 总结 7.9 练习 复习题 第8章 继承和虚函数 8.1 为什么继承如此重要 8.1.1 IceCreamDialog实例 8.1.2 Counter类实例 8.2 继承基础 8.2.1 Counter和DeluxeCounter实例 8.2.2 保护成员 8.2.3 员工、老板和CEO 8.3 访问控制符的规范和多继承 8.4 继承、构造和析构 8.4.1 构造函数和析构函数回顾 8.4.2 基类和派生类的默认构造函数——没有参数 8.4.3 在重载的构造函数中使用参数 8.4.4 基类和派生类的析构函数 8.4.5 医生也是人 8.4.6 关于派生类和基类构造函数的规则 8.5 多态和虚函数 8.5.1 多态——同个接口,不同的行为 8.5.2 什么是虚函数 8.5.3 虚函数的作用 8.6 总结 8.7 练习 复习题 附录A 学习使用Visual C++2005Express Edition 附录B C++关键字表 附录C C++运算符 附录D ASCII码 附录E 位、字节、内存和十六进制表示 附录F 文件输入/输出 附录G 部分C++类 附录H 多文件程序 附录I Microsoft visual C++2005Express Edit
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值