一文详解C++20新特性

 更新时间:2026年06月04日 09:14:46   作者:剑锋所指,所向披靡!  
本文主要介绍了一文详解C++20新特性,包括模块、协程、范围、日期时区、格式化等并发等特性介绍,替代头文件、提升编译效率、支持异步逻辑、增强日期处理、类型安全格式化及简化并发编程

1、模块

C++ 20 中正式引入了模块的概念,模块是一个用于在翻译单元间分享声明和定义的语言特性。它们可以在某些地方替代使用头文件。
其主要优点如下:

  1. 没有头文件。
  2. 声明实现仍然可分离, 但非必要。
  3. 可以显式指定导出哪些类或函数。
  4. 不需要头文件重复引入宏(include guards)。
  5. 模块之间名称可以相同,并且不会冲突。
  6. 模块只处理一次,编译更快(头文件每次引入都需要处理,需要通过 pragma once 约束)。7. 预处理宏只在模块内有效。
  7. 模块的引入与引入顺序无关。

用法

  1. 定义模块(math.ixx)
// 模块声明(模块名:math)
export module math;

// 导出函数(外部可访问)
export int add(int a, int b) {
    return a + b;
}

// 内部函数(仅模块内可见)
int mul(int a, int b) {
    return a * b;
}
  1. 使用模块(main.cpp)
// 导入模块(无需头文件,直接用)
import math;
#include <iostream>

int main() {
    std::cout << add(2, 3) << std::endl; // 输出5(可访问导出的add)
    // std::cout << mul(2, 3) << std::endl; // 编译错误:mul未导出
    return 0;
}

2、协程

C++20 引入无栈协程(非协程库,仅底层机制),是可挂起 / 恢复的特殊函数(非 main 函数),支持用同步写法实现异步逻辑;函数内含co_await/co_yield/co_return任一关键字即为协程,协程不抢占内核调度,仅由线程调用。

关键字作用
co_yield some_value挂起协程并保存状态,向调用者返回some_value
co_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
一般情况: 自动生成所有的比较操作符, 如果对象是结构体则逐个比较, 可以用下面代码代替所有的比较运算符

auto X::operator<=>(const Y&) = default;
int num1 = 100, num2 = 100;
if ((num1 <=> num2) < 0) {
cout << "num1 < num2" << endl;}
else if ((num1 <=> num2) > 0) {
cout << "num1 > num2" << endl;}
else {
cout << "num1 = num2" << endl;}

4、范围 ranges

C++20 引入std::ranges(范围库),是对传统 STL 算法的增强,以 “范围”(容器、数组、视图等)为核心,简化遍历 / 算法调用,支持链式操作,且兼容原有 STL 容器,大幅提升代码简洁性和可读性。

#include <ranges>
#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> vec = {1,2,3,4,5};
    // 范围遍历:自动迭代,无需手动写begin()/end()
    for (int i : vec | ranges::views::filter([](int x){ return x%2==0; })) {
        cout << i << " "; // 输出:2 4
    }
    return 0;
}

5、日期和时区

C++20 引入std::chrono增强的日期 / 时区库,首次标准化了日期(年 / 月 / 日)、时间(时 / 分 / 秒)和时区的统一处理,替代传统零散的时间操作方式,支持本地时间、UTC 时间、时区转换等核心能力。

#include <chrono>
#include <iostream>
using namespace std;
using namespace chrono;

int main() {
    // 1. 获取当前系统时间(UTC)
    auto now_utc = system_clock::now();
    // 转换为日期(年/月/日)
    year_month_day ymd = floor<days>(now_utc);
    cout << ymd.year() << "-" << ymd.month() << "-" << ymd.day() << endl;

    // 2. 时区转换(UTC→本地时区)
    zoned_time local_tz{current_zone(), now_utc};
    cout << "本地时间:" << local_tz << endl;

    return 0;
}

6、格式化

C++20 引入std::format(格式化库),替代传统的printf/cout拼接,支持类型安全的字符串格式化

#include <format>
#include <string>
#include <iostream>
using namespace std;

int main() {
    // 基础格式化:替代printf("%d + %d = %d", a, b, a+b)
    int a = 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.14

    return 0;
}

7、跨度

C++20 引入std::span(跨度),是对连续内存区域(数组、vector、C 数组等)的「轻量级只读 / 可写视图」,仅存储指针 + 长度,无内存拷贝,可安全替代裸指针 / 数组,简化连续内存的访问与传递。

#include <span>
#include <vector>
#include <iostream>
using namespace std;

// 替代传统的「指针+长度」传参,更安全
void print_span(span<int> s) {
    for (int i : s) cout << i << " ";
}

int main() {
    int arr[] = {1,2,3,4};
    vector<int> vec = {5,6,7};
    
    // 1. 绑定数组(自动推导长度)
    span<int> s1(arr); 
    print_span(s1); // 输出:1 2 3 4
    
    // 2. 绑定vector(无拷贝,仅视图)
    span<int> s2(vec);
    s2[0] = 10; // 修改视图会同步修改原vector
    cout << vec[0] << endl; // 输出:10
    
    // 3. 切片(取部分元素)
    span<int> s3 = s1.subspan(1, 2); // 从索引1开始,取2个元素
    print_span(s3); // 输出:2 3
    
    return 0;
}

8、并发

C++20 在原有并发基础上增强了并发能力,核心新增std::jthread(可自动 join 的线程)、std::latch/barrier(同步原语)、std::stop_token(线程取消机制),同时完善原子操作和异步任务,让并发编程更安全、易用,减少手动管理线程的出错风险。

  1. std::jthread(安全线程,替代 std::thread)增强版线程,析构自动 join,支持取消
#include <jthread>
#include <iostream>
using namespace std;

void task(int n) {
    cout << "线程执行:" << n << endl;
}

int main() {
    // jthread析构时自动join,无需手动调用(避免std::thread的析构崩溃)
    jthread t(task, 10); 
    // 无需写t.join(),t销毁时自动完成
    return 0;
}
  1. 线程取消(stop_token + jthread)配合 jthread 实现安全的线程取消
void cancelable_task(stop_token st, int n) {
    for (int i=0; i<n; ++i) {
        // 检查是否收到取消信号
        if (st.stop_requested()) {
            cout << "线程被取消" << endl;
            return;
        }
        cout << "执行中:" << i << endl;
    }
}

int main() {
    jthread t(cancelable_task, 100);
    // 发送取消信号
    t.request_stop(); 
    return 0;
}
  1. std::latch(一次性同步屏障)一次性同步屏障,等待指定数量线程就绪
#include <latch>
#include <vector>

int main() {
    latch l(3); // 需3个线程到达后,主线程才继续
    vector<jthread> threads;
    
    for (int i=0; i<3; ++i) {
        threads.emplace_back([&l, i]() {
            cout << "线程" << i << "就绪" << endl;
            l.count_down(); // 计数减1
        });
    }
    l.wait(); // 等待所有线程就绪
    cout << "所有线程就绪,主线程继续" << endl;
    return 0;
}

到此这篇关于一文详解C++20新特性的文章就介绍到这了,更多相关C++20新特性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++特殊类设计及类型转换举例详解

    C++特殊类设计及类型转换举例详解

    这篇文章主要介绍了C++中如何设计不能被拷贝、只能在堆上或栈上创建对象的类、不能被继承的类以及单例模式的实现方法,还讨论了C++中的类型转换,需要的朋友可以参考下
    2025-05-05
  • opengl实现直线扫描算法和区域填充算法

    opengl实现直线扫描算法和区域填充算法

    这篇文章主要为大家详细介绍了opengl实现直线扫描算法和区域填充算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C语言冒泡排序法的实现(升序排序法)

    C语言冒泡排序法的实现(升序排序法)

    这篇文章主要介绍了C语言冒泡排序法的实现(升序排序法),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • C++实现LeetCode(904.水果装入果篮)

    C++实现LeetCode(904.水果装入果篮)

    这篇文章主要介绍了C++实现LeetCode(904.水果装入果篮),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • 老生常谈C++ explicit关键字

    老生常谈C++ explicit关键字

    这篇文章主要介绍了C++ explicit关键字,explicit关键字只需用于类内的单参数构造函数前面,由于无参数的构造函数和多参数的构造函数总是显式调用,这种情况在构造函数前加explicit无意义,需要的朋友可以参考下
    2023-03-03
  • 简单掌握桶排序算法及C++版的代码实现

    简单掌握桶排序算法及C++版的代码实现

    桶排序是将要排序的算法按桶分组排序之后再遍历汇总的一种线性排序算法,下面就让我们来通过小例子简单掌握桶排序算法及C++版的代码实现^^
    2016-07-07
  • C++瓦片地图坐标转换的实现详解

    C++瓦片地图坐标转换的实现详解

    常见的瓦片地图有矩形、菱形、正六边形几种。此文章主要讨论菱形瓦片,也就是大家常说的2.5D,斜45度瓦片地图。比如《红警2》、《帝国时代2》都是采用这种技术
    2022-09-09
  • 浅析C++中的间接宏函数

    浅析C++中的间接宏函数

    这篇文章主要介绍了C++中的间接宏函数,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • C++中VTK9.3.0刻度标签重叠的问题记录

    C++中VTK9.3.0刻度标签重叠的问题记录

    这篇文章主要介绍了C++中VTK9.3.0刻度标签重叠的问题,本文采用VTK9.3.0版本,其他版本如VKT8.0亦有同样的问题,需要的朋友可以参考下
    2024-06-06
  • OpenCV实现帧间差分法详解

    OpenCV实现帧间差分法详解

    这篇文章主要为大家详细介绍了OpenCV实现帧间差分法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03

最新评论