C++20 是继 C++17 之后的重大更新,引入了多项革命性特性,显著提升了代码的简洁性、安全性和性能。以下是其核心语言与标准库改进的详细分类:
一、核心语言特性
1. 概念(Concepts)
- 功能:约束模板参数类型,增强模板代码的可读性和错误提示。
- 定义概念:
template<typename T> concept Sortable = requires(T a) { { a < a } -> std::convertible_to<bool>; // 要求支持 < 运算符 requires std::swappable<T>; // 要求可交换 };
- 使用概念:
template<Sortable T> void sort(T& container) { /* ... */ } // 仅接受满足 Sortable 的类型 // 简化语法 void print(const std::integral auto& value) { /* 仅整数类型 */ }
2. 协程(Coroutines)
- 功能:简化异步编程和生成器模式,支持挂起与恢复函数执行。
- 关键字:
co_await
,co_yield
,co_return
。 - 生成器示例:
#include <coroutine> generator<int> sequence() { for (int i = 0; ; ++i) { co_yield i; // 每次调用生成一个值并挂起 } } auto gen = sequence(); std::cout << gen.next(); // 0 std::cout << gen.next(); // 1
3. 模块(Modules)
- 功能:替代头文件(
#include
),减少编译时间与依赖问题。 - 语法:
// math.ixx (模块接口文件) export module math; export int add(int a, int b) { return a + b; } // main.cpp import math; int main() { add(2, 3); // 使用模块函数 }
4. 三路比较运算符(<=>
,Spaceship Operator)
- 功能:简化比较运算符的生成,自动推导
==
,!=
,<
,>
,<=
,>=
。 - 示例:
struct Point { int x, y; auto operator<=>(const Point&) const = default; // 自动生成所有比较运算符 }; Point a{1, 2}, b{3, 4}; bool cmp = (a < b); // 自动比较 x 和 y
5. 范围 for
循环的初始化语句
- 功能:在范围
for
循环中声明局部变量。for (auto vec = getVector(); auto& x : vec) { x *= 2; // 循环内使用 vec }
6. constexpr
的增强
- 支持:动态内存分配、虚函数、
try-catch
(但异常必须在编译时处理)。 - 示例:
constexpr int compileTimeSum() { int* arr = new int[3]{1, 2, 3}; // 编译期动态分配 int sum = arr[0] + arr[1] + arr[2]; delete[] arr; return sum; } static_assert(compileTimeSum() == 6);
7. Lambda 捕获的增强
- 允许捕获
[this]
和成员变量:struct MyClass { int value = 42; auto getLambda() { return [this] { return value; }; // 捕获 this return [=, *this] { return value; }; // 捕获当前对象的副本 } };
二、标准库更新
1. 范围库(Ranges)
- 功能:提供声明式语法操作容器,支持惰性求值与管道操作符
|
。 - 示例:
#include <ranges> std::vector<int> vec = {1, 2, 3, 4, 5}; auto even = vec | std::views::filter([](int x) { return x % 2 == 0; }) | std::views::transform([](int x) { return x * 2; }); for (auto x : even) { /* 4, 8 */ }
2. std::format
- 功能:类型安全的格式化库,替代
printf
和iostream
。 - 示例:
#include <format> std::string s = std::format("Hello {}! The answer is {:.2f}.", "World", 3.14159); // 输出:Hello World! The answer is 3.14.
3. std::span
- 功能:非占有式连续内存视图(如数组、
vector
),避免传递指针和大小。 - 示例:
void print(std::span<int> data) { for (int x : data) std::cout << x << " "; } std::vector<int> vec = {1, 2, 3}; int arr[] = {4, 5, 6}; print(vec); // 1 2 3 print(arr); // 4 5 6
4. std::jthread
- 功能:自动加入线程(RAII 封装),支持协作中断。
- 示例:
#include <thread> void task(std::stop_token st) { while (!st.stop_requested()) { /* 定期检查中断 */ } } std::jthread t(task); // 析构时自动调用 request_stop() 和 join()
5. 原子智能指针(std::atomic<std::shared_ptr>
)
- 功能:线程安全的
shared_ptr
原子操作。std::atomic<std::shared_ptr<int>> ptr; ptr.store(std::make_shared<int>(42)); auto local = ptr.load(); // 原子读取
6. 日历与时区库(<chrono>
扩展)
- 功能:处理日期、时间和时区转换。
- 示例:
#include <chrono> using namespace std::chrono; auto now = system_clock::now(); auto tomorrow = floor<days>(now) + 24h; std::cout << std::format("{:%F %T}", tomorrow); // 输出日期时间
三、其他改进
1. 位操作库(<bit>
)
- 功能:跨平台位运算(如字节序转换、位计数)。
#include <bit> uint32_t x = 0x12345678; uint32_t y = std::byteswap(x); // 0x78563412(小端转大端)
2. constinit
关键字
- 功能:强制变量在编译时初始化,避免静态初始化顺序问题。
constinit static int global = 42; // 必须在编译时初始化
3. 条件 explicit
- 功能:根据编译期条件决定构造函数是否
explicit
。template<bool Enable> struct MyType { explicit(Enable) MyType(int) {} // 条件 explicit }; MyType<true> t1 = 42; // 错误:构造函数为 explicit MyType<false> t2 = 42; // 合法
四、编译器支持
- GCC:10.0+ 支持大部分特性。
- Clang:12.0+ 完全支持。
- MSVC:Visual Studio 2019 16.10+ 支持。
五、总结
C++20 的核心改进方向包括:
- 泛型编程革命:概念(Concepts)约束模板,提升代码可读性与错误提示。
- 异步与并发:协程简化异步代码,
std::jthread
和原子智能指针增强线程安全。 - 编译期能力:
constexpr
支持动态内存,模块(Modules)加速编译。 - 现代化工具:范围库(Ranges)、
std::format
、std::span
简化常用操作。
推荐优先掌握:
- 概念(Concepts) 和 范围库(Ranges) 提升泛型代码质量。
- 模块(Modules) 优化大型项目管理。
- 协程(Coroutines) 为异步开发提供新范式。
C++20 标志着现代 C++ 的成熟,适用于高性能计算、系统编程和复杂应用开发。