乐途乐途
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
  • C++ 学习路径
  • 第1章 C++概述与开发环境

    • C++ 语言概述与编译模型
    • 第一个 C++ 程序与规范
    • 开发环境配置
    • 预处理指令详解
  • 第2章 基本语法与类型系统

    • 变量与基本类型
    • 类型转换
    • 枚举类型
    • 引用与指针
    • 数组与 stdarray
    • 字符串与原始字符串字面量
    • const 与 constexpr
    • nullptr 与空指针
    • 类型推导 auto 与 decltype
    • 基于范围的 for 循环
    • 值类别全面解析
    • char16_t 与 char32_t
    • static_assert 编译期断言
  • 第3章 函数与重载

    • 函数声明与定义
    • 函数重载
    • 默认参数与内联函数
    • Lambda 表达式
    • 函数对象与 stdfunction
    • 后置返回类型与 noexcept
  • 第4章 类与对象

    • 类的基本定义
    • 构造函数与析构函数
    • 拷贝控制
    • 移动构造函数与移动赋值
    • 列表初始化与类内初始化器
    • 静态成员与嵌套类
    • 友元
    • =default 与 =delete
  • 第5章 继承与多态

    • 继承基础
    • 虚函数与多态
    • 虚函数表与动态绑定原理
    • 虚析构函数
    • 抽象类与纯虚函数
    • 多重继承与虚继承
    • 继承构造函数
  • 第6章 运算符重载

    • 运算符重载基础
    • 算术与关系运算符重载
    • 赋值与移动运算符重载
    • 特殊运算符重载
  • 第7章 模板与泛型编程

    • 函数模板
    • 类模板
    • 模板特化与偏特化
    • 可变参数模板
    • 别名模板与模板模板参数
    • SFINAE 与类型萃取
    • 依赖名与 typename/template 关键字
  • 第8章 异常处理

    • 异常处理机制
    • noexcept 与异常安全
    • RAII 与异常安全实践
  • 第9章 内存管理与智能指针

    • 动态内存与内存分区
    • RAII 惯用法
    • unique_ptr
    • shared_ptr 与 weak_ptr
    • 内存管理最佳实践
  • 第10章 右值引用与移动语义

    • 右值引用与值类别深度解析
    • std::move 原理与使用
    • 完美转发与 std::forward
    • 移动语义性能对比与最佳实践
  • 第11章 STL容器

    • vector 深度剖析
    • deque 内部机制
    • list 与 forward_list
    • map 与 set 深度解析
    • unordered 容器与哈希原理
    • array 与 tuple
    • 容器适配器
    • 容器选择全景指南
  • 第12章 STL算法与迭代器

    • 迭代器体系全解
    • 非变异算法
    • 变异算法
    • 排序与二分算法
    • Lambda 与算法组合
    • std::random 随机数库
    • 自定义迭代器开发
  • 第13章 IO流与文件

    • 标准 IO 流
    • 格式化输出控制
    • 文件流操作
    • 字符串流
    • std::regex 正则表达式
  • 第14章 并发与多线程

    • thread 基础与线程管理
    • mutex 与 lock_guard
    • unique_lock 与 condition_variable
    • thread_local 线程局部存储
    • atomic 与内存序
    • future 与 async 异步编程
    • std::chrono 时间库
  • 第15章 现代C++新特性

    • 从 C++11 到 C++20 演进路线
    • C++14 关键新特性
    • C++17 关键新特性
    • C++20 核心特性速览
  • 第16章 面试考点与最佳实践

    • C++ 综合最佳实践清单
    • 高频面试题精讲
    • 多线程面试题与实战
    • 内存管理常见陷阱与排查
  • 附录

    • C++ 核心知识点
    • C++ 专业术语

C++20 核心特性速览

定义与作用

C++20 是 C++ 史上最大的更新之一,引入了四大核心特性:Concepts(概念)、Ranges(范围库)、Coroutines(协程)和 Modules(模块),以及三路比较运算符 <=>、std::span 和 std::format 等实用改进。

核心原理

C++20 四大支柱

完整示例

示例一:Concepts 约束矩阵运算

场景说明:白歌用 Concepts 约束飞翔科技数学库的模板参数。

#include <iostream>
#include <concepts>
#include <vector>
#include <type_traits>

// 定义 Concept:只接受数值类型
template<typename T>
concept Numeric = std::is_arithmetic_v<T>;

// 受约束的矩阵类
template<Numeric T>
class Matrix {
public:
    Matrix(size_t rows, size_t cols)
        : rows_(rows), cols_(cols), data_(rows * cols) {}

    T& at(size_t r, size_t c) { return data_[r * cols_ + c]; }
    const T& at(size_t r, size_t c) const { return data_[r * cols_ + c]; }

    // Concepts 直接写在参数上
    void fill(Numeric auto val) {
        std::fill(data_.begin(), data_.end(), val);
    }

    size_t rows() const { return rows_; }
    size_t cols() const { return cols_; }

    void print(const char* name) const {
        std::cout << name << " (" << rows_ << "x" << cols_ << "):\n";
        for (size_t i = 0; i < rows_; ++i) {
            std::cout << "  ";
            for (size_t j = 0; j < cols_; ++j)
                std::cout << at(i, j) << " ";
            std::cout << "\n";
        }
    }

private:
    size_t rows_, cols_;
    std::vector<T> data_;
};

// 仅对 Numeric 类型生效
template<Numeric T>
Matrix<T> addMatrices(const Matrix<T>& a, const Matrix<T>& b) {
    Matrix<T> result(a.rows(), a.cols());
    for (size_t i = 0; i < a.rows(); ++i)
        for (size_t j = 0; j < a.cols(); ++j)
            result.at(i, j) = a.at(i, j) + b.at(i, j);
    return result;
}

// 三路比较运算符:自动生成 ==, !=, <, <=, >, >=
struct ServerLoad {
    double cpu;
    double memory;
    int activeConnections;

    auto operator<=>(const ServerLoad&) const = default;
};

int main() {
    std::cout << "=== 飞翔科技 C++20 特性展示 ===\n\n";

    // 1. Concepts
    Matrix<int> a(2, 3);
    a.fill(1);
    a.at(0, 1) = 3;

    Matrix<int> b(2, 3);
    b.fill(2);
    b.at(1, 2) = 5;

    a.print("矩阵 A");
    b.print("矩阵 B");

    auto c = addMatrices(a, b);
    c.print("A + B");

    // 以下将编译失败(Concept 约束)
    // Matrix<std::string> strMat(2, 2);  // ❌ 不满足 Numeric concept

    // 2. 三路比较 <=>
    std::cout << "\n--- 三路比较 ---\n";
    ServerLoad s1{75.0, 60.0, 1000};
    ServerLoad s2{80.0, 55.0, 1200};
    ServerLoad s3{75.0, 60.0, 1000};

    std::cout << std::boolalpha;
    std::cout << "s1 == s3: " << (s1 == s3) << "\n";
    std::cout << "s1 != s2: " << (s1 != s2) << "\n";
    std::cout << "s1 <  s2: " << (s1 < s2) << "\n";
    std::cout << "s2 >  s1: " << (s2 > s1) << "\n";
    // <=> 比较规则:先 cpu,再 memory,最后 activeConnections

    // 3. span:安全数组视图
    std::cout << "\n--- span 安全视图 ---\n";
    std::vector<int> loads{10, 25, 50, 75, 90, 55, 30};

    auto printSpan = [](std::span<const int> s, const char* label) {
        std::cout << label << ": ";
        for (auto v : s) std::cout << v << " ";
        std::cout << " (size=" << s.size() << ")\n";
    };

    printSpan(loads, "完整视图");

    std::span<int> mid = std::span(loads).subspan(2, 3);
    mid[0] = 99;  // 修改视图即修改原数据
    printSpan(loads, "修改后  ");

    // 4. Ranges 管道式操作
    std::cout << "\n--- Ranges 管道 ---\n";
    std::vector<int> data{5, 12, 3, 8, 15, 7, 20, 1, 9};

    auto evenSquares = data
        | std::views::filter([](int n) { return n % 2 == 0; })
        | std::views::transform([](int n) { return n * n; })
        | std::views::take(3);

    std::cout << "偶数平方 (前3个): ";
    for (auto v : evenSquares) std::cout << v << " ";
    std::cout << "\n";

    // Ranges 排序
    std::ranges::sort(data);
    std::cout << "排序后: ";
    for (auto v : data) std::cout << v << " ";
    std::cout << "\n";
}

预期输出:

=== 飞翔科技 C++20 特性展示 ===

矩阵 A (2x3):
  1 3 1
  1 1 1
矩阵 B (2x3):
  2 2 2
  2 2 5
A + B (2x3):
  3 5 3
  3 3 6

--- 三路比较 ---
s1 == s3: true
s1 != s2: true
s1 <  s2: true
s2 >  s1: true

--- span 安全视图 ---
完整视图: 10 25 50 75 90 55 30  (size=7)
修改后  : 10 25 99 75 90 55 30  (size=7)

--- Ranges 管道 ---
偶数平方 (前3个): 144 64 400
排序后: 1 3 5 7 8 9 12 15 20

逐段分析:

  • Concept Numeric 约束模板参数,错误信息清晰
  • = default 的 <=> 自动生成全部六种比较运算符
  • span 是轻量级数组视图,不拥有数据,带边界检查
  • Ranges 的 | 管道语法替代嵌套函数调用,延迟求值

示例二:format 替换 iostream

场景说明:黄俪用 std::format 重构飞翔科技日志输出。

#include <iostream>
#include <format>
#include <string>
#include <chrono>
#include <vector>

struct ApiMetric {
    std::string endpoint;
    int statusCode;
    double latencyMs;
    size_t bytesTransferred;
};

int main() {
    std::cout << "=== 飞翔科技格式化日志 (C++20 format) ===\n\n";

    // format 替代 ostringstream
    std::string title = std::format("=== {} v{}.{}.{} ===",
        "飞翔-API-Gateway", 2, 1, 0);
    std::cout << title << "\n\n";

    // 精确控制格式
    double hitRate = 95.237;
    std::cout << std::format("缓存命中率: {:.2f}%\n", hitRate);  // 保留2位
    std::cout << std::format("十六进制: {:#x}\n", 255);           // 0xff
    std::cout << std::format("前导零: {:08d}\n", 42);             // 00000042

    // 表格对齐
    std::cout << "\n";
    std::cout << std::format("{:<20} {:>6} {:>10} {:>12}\n",
        "接口", "状态", "延迟(ms)", "传输字节");
    std::cout << std::string(52, '-') << "\n";

    std::vector<ApiMetric> metrics{
        {"/api/v1/users",    200, 12.5, 1024},
        {"/api/v1/orders",   200, 45.8, 8192},
        {"/api/v1/products", 500, 0.0,  0},
    };

    for (const auto& m : metrics) {
        std::cout << std::format("{:<20} {:>6} {:>10.1f} {:>12}\n",
            m.endpoint, m.statusCode, m.latencyMs, m.bytesTransferred);
    }

    // 编译期 format 检查(C++20 编译期字符串)
    // std::format("{:d}", "oops");  // ❌ 编译错误!类型不匹配
}

预期输出:

=== 飞翔科技格式化日志 (C++20 format) ===

=== 飞翔-API-Gateway v2.1.0 ===

缓存命中率: 95.24%
十六进制: 0xff
前导零: 00000042

接口                   状态    延迟(ms)       传输字节
----------------------------------------------------
/api/v1/users           200       12.5         1024
/api/v1/orders          200       45.8         8192
/api/v1/products        500        0.0            0

逐段分析:

  • std::format 类型安全,格式串与参数不匹配时编译报错
  • 类似 Python 的 str.format 语法,{} 占位
  • {:.2f} 控制精度,{:<20} 左对齐,{:>6} 右对齐
  • 比 iostream 更简洁,无需 setw/setprecision 等 manipulator

易错场景与面试考点

易错场景

1. span 不拥有数据

std::span<int> makeSpan() {
    std::vector<int> v{1, 2, 3};
    return std::span(v);  // ❌ v 析构后 span 悬挂
}

2. Ranges 视图是惰性的

auto v = data | std::views::filter(pred);
// 实际过滤在遍历时才执行
// 修改源数据后再遍历,看到的是最新数据

3. <=> 不等于 ==

// operator<=> 不自动生成 operator==(C++20 行为)
// 需要显式 default 或单独定义
// [注:此细节在不同实现中可能有差异]

面试考点

特性要点
Conceptstemplate<Concept T> 约束模板,比 SFINAE 清晰
requires 子句requires std::integral<T> 细粒度约束
Rangesstd::views::filter/transform/take 管道式延迟求值
协程co_await/co_yield/co_return,编译器生成状态机
<=>三路比较,= default 自动生成全部比较运算符
span非拥有型数组视图,subspan/first/last
format类型安全格式化,编译期检查
Modulesimport std; 替代 #include,减少编译时间
上一页
C++17 关键新特性