一文详解C++20新特性

发布时间:2026/9/15 1:16:37
一文详解C++20新特性
C 20 中正式引入了模块的概念模块是一个用于在翻译单元间分享声明和定义的语言特性。它们可以在某些地方替代使用头文件。其主要优点如下没有头文件。声明实现仍然可分离, 但非必要。可以显式指定导出哪些类或函数。不需要头文件重复引入宏include guards。模块之间名称可以相同并且不会冲突。模块只处理一次编译更快头文件每次引入都需要处理需要通过 pragma once 约束。7. 预处理宏只在模块内有效。模块的引入与引入顺序无关。用法定义模块math.ixx123456789101112// 模块声明模块名mathexport module math;// 导出函数外部可访问exportintadd(inta,intb) {returna b;}// 内部函数仅模块内可见intmul(inta,intb) {returna * b;}使用模块main.cpp123456789// 导入模块无需头文件直接用import math;#include iostreamintmain() {std::cout add(2, 3) std::endl;// 输出5可访问导出的add// std::cout mul(2, 3) std::endl; // 编译错误mul未导出return0;}2、协程C20 引入无栈协程非协程库仅底层机制是可挂起 / 恢复的特殊函数非 main 函数支持用同步写法实现异步逻辑函数内含co_await/co_yield/co_return任一关键字即为协程协程不抢占内核调度仅由线程调用。关键字作用co_yield some_value挂起协程并保存状态向调用者返回some_valueco_await some_awaitable若some_awaitable未就绪挂起协程并保存状态就绪后恢复执行co_return some_value终止协程向调用者返回some_value协程彻底结束3、 三向比较运算符比较结果如下(a b) 0 // 如果 a b 则为 true(a b) 0 // 如果 a b 则为 true(a b) 0 // 如果 a 与 b 相等或者等价 则为 true类似于C的strcmp 函数返回-1, 0, 1一般情况: 自动生成所有的比较操作符, 如果对象是结构体则逐个比较, 可以用下面代码代替所有的比较运算符1auto X::operator(constY) default;1234567intnum1 100, num2 100;if((num1 num2) 0) {cout num1 num2 endl;}elseif((num1 num2) 0) {cout num1 num2 endl;}else{cout num1 num2 endl;}4、范围 rangesC20 引入std::ranges范围库是对传统 STL 算法的增强以 “范围”容器、数组、视图等为核心简化遍历 / 算法调用支持链式操作且兼容原有 STL 容器大幅提升代码简洁性和可读性。12345678910111213#include ranges#include vector#include iostreamusingnamespacestd;intmain() {vectorint vec {1,2,3,4,5};// 范围遍历自动迭代无需手动写begin()/end()for(inti : vec | ranges::views::filter([](intx){returnx%20; })) {cout i ;// 输出2 4}return0;}5、日期和时区C20 引入std::chrono增强的日期 / 时区库首次标准化了日期年 / 月 / 日、时间时 / 分 / 秒和时区的统一处理替代传统零散的时间操作方式支持本地时间、UTC 时间、时区转换等核心能力。123456789101112131415161718#include chrono#include iostreamusingnamespacestd;usingnamespacechrono;intmain() {// 1. 获取当前系统时间UTCauto now_utc system_clock::now();// 转换为日期年/月/日year_month_day ymd floordays(now_utc);cout ymd.year() - ymd.month() - ymd.day() endl;// 2. 时区转换UTC→本地时区zoned_time local_tz{current_zone(), now_utc};cout 本地时间 local_tz endl;return0;}6、格式化C20 引入std::format格式化库替代传统的printf/cout拼接支持类型安全的字符串格式化1234567891011121314151617#include format#include string#include iostreamusingnamespacestd;intmain() {// 基础格式化替代printf(%d %d %d, a, b, ab)inta 5, b 3;string res format({} {} {}, a, b, a b);cout res endl;// 输出5 3 8// 带格式控制指定宽度、精度、进制cout format(数字{:5d}十六进制{:x}浮点数{:.2f}, 123, 255, 3.1415) endl;// 输出数字 123十六进制ff浮点数3.14return0;}7、跨度C20 引入std::span跨度是对连续内存区域数组、vector、C 数组等的「轻量级只读 / 可写视图」仅存储指针 长度无内存拷贝可安全替代裸指针 / 数组简化连续内存的访问与传递。1234567891011121314151617181920212223242526272829#include span#include vector#include iostreamusingnamespacestd;// 替代传统的「指针长度」传参更安全voidprint_span(spanint s) {for(inti : s) cout i ;}intmain() {intarr[] {1,2,3,4};vectorint vec {5,6,7};// 1. 绑定数组自动推导长度spanint s1(arr);print_span(s1);// 输出1 2 3 4// 2. 绑定vector无拷贝仅视图spanint s2(vec);s2[0] 10;// 修改视图会同步修改原vectorcout vec[0] endl;// 输出10// 3. 切片取部分元素spanint s3 s1.subspan(1, 2);// 从索引1开始取2个元素print_span(s3);// 输出2 3return0;}8、并发C20 在原有并发基础上增强了并发能力核心新增std::jthread可自动 join 的线程、std::latch/barrier同步原语、std::stop_token线程取消机制同时完善原子操作和异步任务让并发编程更安全、易用减少手动管理线程的出错风险。std::jthread安全线程替代 std::thread增强版线程析构自动 join支持取消1234567891011121314#include jthread#include iostreamusingnamespacestd;voidtask(intn) {cout 线程执行 n endl;}intmain() {// jthread析构时自动join无需手动调用避免std::thread的析构崩溃jthread t(task, 10);// 无需写t.join()t销毁时自动完成return0;}线程取消stop_token jthread配合 jthread 实现安全的线程取消1234567891011121314151617voidcancelable_task(stop_token st,intn) {for(inti0; in; i) {// 检查是否收到取消信号if(st.stop_requested()) {cout 线程被取消 endl;return;}cout 执行中 i endl;}}intmain() {jthread t(cancelable_task, 100);// 发送取消信号t.request_stop();return0;}std::latch一次性同步屏障一次性同步屏障等待指定数量线程就绪1234567891011121314151617#include latch#include vectorintmain() {latch l(3);// 需3个线程到达后主线程才继续vectorjthread threads;for(inti0; i3; i) {threads.emplace_back([l, i]() {cout 线程 i 就绪 endl;l.count_down();// 计数减1});}l.wait();// 等待所有线程就绪cout 所有线程就绪主线程继续 endl;return0;}到此这篇关于一文详解C20新特性的文章就介绍到这了,