云计算百科
云计算领域专业知识百科平台

C++ 的史诗级进化:从C++98到C++20

从C++98到C++20

    • C++ 的史诗级进化:从基石到现代摩天大楼 (C++98 – C++20 详解,含示例)
      • C++98/03:奠基时代 —— 经典 C++ 的核心骨架
      • C++11:现代化革命 —— 重塑 C++ 的里程碑
      • C++14:精炼与完善 —— 让现代 C++ 更好用
      • C++17:可用性飞跃 —— 更现代、更便捷
      • C++20:再次飞跃 —— 引入基础性变革
      • C++23 及未来:持续前行
      • 结语:成为现代 C++ 开发者

这篇文章深入探讨了 C++ 从 C++98/03 到 C++20 的主要版本演进,并为每个主要特性提供了代码示例和详细的解释。


C++ 的史诗级进化:从基石到现代摩天大楼 (C++98 – C++20 详解,含示例)

C++,这门在软件开发领域屹立数十载的语言,早已不是当年吴下阿蒙。它如同一座不断扩展、持续翻新的宏伟建筑,从 C++98/03 奠定的坚实地基,到 C++11 拔地而起的现代化主体结构,再经过 C++14/17 的精心装修和 C++20 增添的炫酷新翼,如今的 C++ 已然是一座功能强大、结构精妙的现代化摩天大楼。

理解这座“大楼”的建造历程,不仅能让我们欣赏其设计的精妙,更能让我们熟练运用其中的各种“设施”,建造出更稳固、更高效、更舒适的“应用程序房间”。无论你是刚拿到“入住钥匙”的新手,还是已在此“居住”多年的老兵,重新审视 C++ 的进化之路,都将获益匪浅。

本文将详细梳理 C++ 各主要标准版本带来的核心新特性,并通过代码示例展示它们的用法和威力。

C++98/03:奠基时代 —— 经典 C++ 的核心骨架

(发布于 1998年,2003年小幅修订)

这个时代确立了 C++ 的核心范式,至今仍是语言的基础。它提供了强大的底层控制能力和抽象机制。

核心特性回顾 (无新增特性,仅回顾基础):

  • 面向对象: 类 (class), 继承, 多态 (virtual 函数)。
  • 模板 (Templates): 泛型编程,STL 的基础。
  • 标准模板库 (STL): 容器 (vector, map 等), 算法 (sort 等), 迭代器。
  • 异常处理: try/catch/throw。
  • 命名空间: namespace 防止命名冲突。
  • RTTI: dynamic_cast, typeid。

主要痛点: 手动内存管理 (new/delete) 易错,类型声明冗长,容器初始化繁琐,无标准并发支持,NULL/0 表示空指针有歧义,模板错误信息难懂。

C++11:现代化革命 —— 重塑 C++ 的里程碑

(发布于 2011年)

C++11 是一次全面的现代化升级,旨在解决 C++98/03 的诸多痛点,大幅提升开发体验和代码质量。

主要新特性详解及示例:

  • auto 类型推导

    • 对比旧版: 无需再写冗长、复杂的类型名,尤其是迭代器。
    • 使用方法: 用 auto 声明变量,编译器自动推导类型。#include <vector>
      #include <string>
      #include <map>
      #include <iostream>

      int main() {
      auto count = 10; // 推导为 int
      auto pi = 3.14159; // 推导为 double
      auto message = std::string("Hello"); // 推导为 std::string

      std::map<int, std::vector<double>> dataMap;
      // … 填充 dataMap …
      // 如果不用 auto,迭代器类型非常长!
      auto it = dataMap.find(42); // it 推导为 std::map<…>::iterator

      if (it != dataMap.end()) {
      std::cout << "Found key 42" << std::endl;
      }
      return 0;
      }

    • 场景: 简化变量声明,提高可读性(当类型明显时)和可维护性。
    • 提升: 大幅减少样板代码。
  • 基于范围的 for 循环

    • 对比旧版: 告别手动迭代器管理 (begin(), end(), ++it)。
    • 使用方法: for (声明 : 范围)。#include <vector>
      #include <iostream>
      #include <map>

      int main() {
      std::vector<int> numbers = {1, 2, 3, 4, 5};
      std::cout << "Numbers: ";
      for (int n : numbers) { // 简单遍历读取
      std::cout << n << " ";
      }
      std::cout << std::endl;

      std::map<std::string, int> ages = {{"Alice", 30}, {"Bob", 25}};
      std::cout << "Ages:" << std::endl;
      for (const auto& pair : ages) { // 使用 const auto& 避免拷贝
      std::cout << " – " << pair.first << " is " << pair.second << std::endl;
      }

      std::cout << "Double numbers: ";
      for (auto& n : numbers) { // 使用 auto& 修改元素
      n *= 2;
      std::cout << n << " ";
      }
      std::cout << std::endl;
      return 0;
      }

    • 场景: 遍历容器、数组、初始化列表等序列。
    • 提升: 代码更简洁、直观、安全。
  • Lambda 表达式

    • 对比旧版: 无需定义独立的函数或 Functor 类来实现简单的局部操作。
    • 使用方法: [捕获](参数) -> 返回类型 { 函数体 }。#include <vector>
      #include <algorithm>
      #include <iostream>

      int main() {
      std::vector<int> v = {1, 5, 2, 8, 3};
      int offset = 10;
      int sum_even = 0;

      // 1. 无捕获,简单比较器
      std::sort(v.begin(), v.end(), [](int a, int b) { return a < b; });

      // 2. 按值捕获 offset
      std::for_each(v.begin(), v.end(), [offset](int x) {
      std::cout << (x + offset) << " ";
      });
      std::cout << std::endl;

      // 3. 按引用捕获 sum_even,并在内部修改
      std::for_each(v.begin(), v.end(), [&sum_even](int x) {
      if (x % 2 == 0) {
      sum_even += x;
      }
      });
      std::cout << "Sum of even numbers: " << sum_even << std::endl; // 输出 10 (2+8)

      // 4. 自动推导返回类型
      auto multiply = [](int a, int b) { return a * b; };
      std::cout << "Multiply 3*4: " << multiply(3, 4) << std::endl; // 输出 12

      return 0;
      }

    • 场景: STL 算法谓词/操作,创建回调,定义局部帮助函数。
    • 提升: 代码更紧凑,逻辑更集中,表达能力强(闭包)。
  • nullptr

    • 对比旧版: 解决了 NULL/0 的类型歧义。
    • 使用方法: 用 nullptr 代替 NULL 或 0 表示空指针。#include <iostream>
      #include <cstddef> // for std::nullptr_t

      void print(int x) { std::cout << "print(int): " << x << std::endl; }
      void print(char* p) { std::cout << "print(char*): " << (p ? p : "null") << std::endl; }

      int main() {
      print(0); // 调用 print(int)
      // print(NULL); // 可能编译错误或调用 print(int)
      print(nullptr); // 清晰地调用 print(char*)
      char* my_ptr = nullptr;
      print(my_ptr); // 调用 print(char*)
      return 0;
      }

    • 场景: 任何需要表示或检查空指针的地方。
    • 提升: 类型安全,代码意图明确。
  • 智能指针 (std::unique_ptr, std::shared_ptr, std::weak_ptr)

    • 对比旧版: 彻底改变手动 new/delete 的模式。
    • 使用方法: 使用 <memory> 头文件中的类管理动态资源。#include <memory>
      #include <iostream>
      #include <vector>

      struct Resource {
      int id;
      Resource(int i) : id(i) { std::cout << "Resource " << id << " acquired\\n"; }
      ~Resource() { std::cout << "Resource " << id << " released\\n"; }
      };

      // unique_ptr 示例
      std::unique_ptr<Resource> create_resource(int id) {
      return std::unique_ptr<Resource>(new Resource(id)); // C++11 方式
      // return std::make_unique<Resource>(id); // C++14 更好
      }

      void use_resource(std::unique_ptr<Resource> res) {
      if (res) std::cout << "Using resource " << res->id << "\\n";
      } // res 离开作用域,资源自动释放

      // shared_ptr 示例
      void share_resource(std::shared_ptr<Resource> res, const std::string& user) {
      std::cout << user << " is using resource " << res->id << " (use count: " << res.use_count() << ")\\n";
      } // res 离开作用域,引用计数减 1

      int main() {
      std::cout << "— unique_ptr —" << std::endl;
      {
      auto r1 = create_resource(1);
      use_resource(std::move(r1)); // 必须移动所有权
      // r1 现在为空
      } // 资源 1 在 use_resource 结束时释放

      std::cout << "\\n— shared_ptr —" << std::endl;
      std::shared_ptr<Resource> r2 = std::make_shared<Resource>(2); // C++11 推荐方式
      std::cout << "Initial use count: " << r2.use_count() << std::endl;
      auto r3 = r2; // 共享所有权
      std::cout << "After copy, use count: " << r2.use_count() << std::endl;
      share_resource(r2, "User A");
      share_resource(r3, "User B");
      std::cout << "Leaving main scope…" << std::endl;
      // r2 和 r3 离开作用域,引用计数归零,资源 2 释放
      return 0;
      }

    • 场景: 管理任何动态分配的资源(内存、文件句柄、锁等)。
    • 提升: 极大地提高了内存安全、异常安全,代码更简洁健壮。
  • 移动语义与右值引用 (&&)

    • 对比旧版: 避免昂贵的资源拷贝,实现高效的资源转移。
    • 使用方法: 实现移动构造函数和移动赋值运算符,使用 std::move 触发移动。#include <vector>
      #include <string>
      #include <utility> // for std::move
      #include <iostream>

      class DataHolder {
      public:
      std::vector<int> data;
      DataHolder(size_t size) : data(size) { std::cout << "DataHolder constructed (size " << size << ")\\n"; }
      ~DataHolder() { std::cout << "DataHolder destroyed\\n"; }
      // 禁用拷贝 (或实现深拷贝)
      DataHolder(const DataHolder&) = delete;
      DataHolder& operator=(const DataHolder&) = delete;
      // 移动构造
      DataHolder(DataHolder&& other) noexcept : data(std::move(other.data)) { // 直接移动 vector 成员
      std::cout << "DataHolder move constructed\\n";
      }
      // 移动赋值
      DataHolder& operator=(DataHolder&& other) noexcept {
      data = std::move(other.data); // 直接移动 vector 成员
      std::cout << "DataHolder move assigned\\n";
      return *this;
      }
      };

      DataHolder create_holder(size_t s) { return DataHolder(s); }

      int main() {
      DataHolder h1 = create_holder(1000); // 移动构造 (或 RVO)
      DataHolder h2(2000);
      DataHolder h3 = std::move(h2); // 显式移动构造
      // h2.data 现在为空
      return 0;
      }

    • 场景: 实现资源管理类,优化函数参数传递和返回值。
    • 提升: 显著提升性能。
  • 初始化列表与统一初始化 ({})

    • 对比旧版: 提供统一、简洁的初始化语法。
    • 使用方法: 使用 {} 初始化变量、容器、类对象。#include <vector>
      #include <map>
      #include <string>

      struct Point { int x; int y; };

      int main() {
      int a = 5; int a_u{5}; // 基本类型
      int arr[] = {1, 2}; int arr_u[]{1, 2}; // 数组
      Point p = {10, 20}; Point p_u{10, 20}; // 聚合体

      std::vector<int> v = {1, 3, 5}; // 容器初始化
      std::map<std::string, int> counts = {{"apple", 2}, {"banana", 5}};

      // 注意区分构造函数调用
      std::vector<int> v1(10); // 10 个默认值 (0)
      std::vector<int> v2{10}; // 1 个元素,值为 10
      return 0;
      }

    • 场景: 各种初始化场景。
    • 提升: 代码一致性、简洁性,容器初始化方便。
  • 并发编程支持

    • 对比旧版: 标准库提供了跨平台并发工具。
    • 使用方法: 使用 <thread>, <mutex>, <atomic>, <future> 等。#include <thread>
      #include <vector>
      #include <iostream>
      #include <atomic>

      std::atomic<int> counter = 0; // 原子计数器,无需锁

      void increment() {
      for (int i = 0; i < 10000; ++i) {
      counter++; // 原子操作
      }
      }

      int main() {
      std::vector<std::thread> threads;
      for (int i = 0; i < 4; ++i) {
      threads.emplace_back(increment);
      }
      for (auto& t : threads) {
      t.join();
      }
      std::cout << "Final counter: " << counter << std::endl; // 应为 40000
      return 0;
      }

    • 场景: 多线程、并行计算、异步任务。
    • 提升: 标准化、可移植的并发能力。
  • override 和 final

    • 对比旧版: 解决了虚函数重写易错和缺乏继承控制的问题。
    • 使用方法: 在派生类虚函数后加 override,在虚函数或类名后加 final。struct Base { virtual void draw() const = 0; };
      struct Circle : Base { void draw() const override; }; // 确保重写
      struct SpecialCircle final : Circle { void draw() const override; }; // SpecialCircle 不能被继承
      // struct MoreSpecial : SpecialCircle {}; // 编译错误
    • 场景: 继承体系设计。
    • 提升: 代码更健壮,设计意图更明确。
  • 默认和删除函数 (= default, = delete)

    • 对比旧版: 提供了显式控制特殊成员函数生成或禁用的方法。
    • 使用方法: 在函数声明后加上 = default 或 = delete。class MyClass {
      public:
      MyClass() = default; // 使用默认构造
      MyClass(int) = delete; // 禁止 int 构造
      virtual ~MyClass() = default; // 使用默认析构(如果是虚的)
      MyClass(const MyClass&) = delete; // 禁止拷贝
      MyClass& operator=(const MyClass&) = delete;
      MyClass(MyClass&&) = default; // 允许默认移动
      MyClass& operator=(MyClass&&) = default;
      };
    • 场景: 控制类的“五/六大特殊成员”,禁止不期望的操作。
    • 提升: 意图清晰,控制精确。
  • constexpr (C++11 基础版)

    • 对比旧版: 引入编译期函数求值能力。
    • 使用方法: 用 constexpr 修饰变量或函数。函数体限制严格。constexpr int MAX_SIZE = 1024;
      constexpr int fib(int n) {
      return (n <= 1) ? n : fib(n1) + fib(n2); // C++11 可能需要更简单的实现
      }
      constexpr int fib_5 = fib(5); // 编译期计算 (如果编译器支持且函数符合要求)
    • 场景: 定义真常量,简单的编译期计算。
    • 提升: 增强编译期能力。
  • C++14:精炼与完善 —— 让现代 C++ 更好用

    (发布于 2014年)

    C++14 主要对 C++11 进行补充和优化,提升易用性。

    主要新特性详解及示例:

  • 通用 Lambda 表达式

    • 对比 C++11: Lambda 参数可以使用 auto。
    • 使用方法: [](auto x, auto y) { … }auto print = [](const auto& value) { std::cout << value << " "; };
      print(10);
      print("hello");
      print(3.14);
    • 场景: 泛型回调,简化模板代码。
    • 提升: Lambda 更灵活通用。
  • Lambda 初始化捕获 / 广义 Lambda 捕获

    • 对比 C++11: 捕获列表支持 [var = expr]。
    • 使用方法: [p = std::move(ptr), count = get_count()] { … }#include <memory>
      #include <utility> // std::move
      auto uptr = std::make_unique<int>(100);
      // 移动 uptr 到 lambda 的成员 p
      auto lambda = [p = std::move(uptr)]() { return *p; };
      std::cout << lambda() << std::endl; // 输出 100
      // uptr 现在是 nullptr
    • 场景: 移动捕获资源,捕获时进行计算。
    • 提升: 解决了 C++11 移动捕获的难题,捕获更强大。
  • 函数返回类型推导

    • 对比 C++11: 函数返回类型可以直接写 auto。
    • 使用方法: auto func(auto param) { return param * 2; }template<typename T>
      auto get_half(T value) { // 编译器推导返回 T/2 的类型
      return value / 2;
      }
      auto half_int = get_half(10); // int
      auto half_double = get_half(5.0); // double
    • 场景: 简化函数声明,尤其模板函数。
    • 提升: 代码更简洁。
  • constexpr 函数限制放宽

    • 对比 C++11: 允许 constexpr 函数包含局部变量、if/switch、循环等。
    • 使用方法: 可以写更像普通函数的 constexpr 函数。constexpr int sum_upto(int n) {
      int sum = 0;
      for (int i = 1; i <= n; ++i) {
      sum += i;
      }
      return sum; // 可以有局部变量和循环
      }
      constexpr int s5 = sum_upto(5); // 编译期计算 15
    • 场景: 更复杂的编译期计算。
    • 提升: constexpr 更实用、易用。
  • 变量模板

    • 新特性: template<typename T> constexpr T pi = …;
    • 使用方法: pi<double>, pi<float>。template<typename T>
      constexpr bool is_integer_type = std::is_integral_v<T>; // is_integral_v 是 C++17 的

      static_assert(is_integer_type<int>);
      static_assert(!is_integer_type<double>);

    • 场景: 类型相关的常量或变量。
    • 提升: 定义方式更自然。
  • 二进制字面量 (0b) 与 数字分隔符 (')

    • 新特性: 0b1010, 1'000'000。
    • 提升: 提高数字字面量的可读性。
  • std::make_unique

    • 新库特性: 补齐 C++11 缺失。
    • 使用方法: auto ptr = std::make_unique<T>(args…);
    • 提升: 创建 unique_ptr 的标准、安全方式。
  • C++17:可用性飞跃 —— 更现代、更便捷

    (发布于 2017年)

    C++17 进一步提升易用性,并引入了多个强大的标准库组件。

    主要新特性详解及示例:

  • 结构化绑定

    • 新特性: auto [x, y, z] = my_tuple;
    • 使用方法: 从 pair, tuple, struct/class(公共成员)中解包。#include <map>
      #include <string>
      #include <tuple>
      #include <iostream>

      int main() {
      std::map<int, std::string> users = {{1, "Alice"}, {2, "Bob"}};
      for (const auto& [id, name] : users) { // 直接获取 key 和 value
      std::cout << "ID: " << id << ", Name: " << name << std::endl;
      }

      std::tuple<double, char, std::string> result{3.14, 'a', "tuple"};
      auto [d_val, c_val, s_val] = result; // 解包 tuple
      std::cout << d_val << ", " << c_val << ", " << s_val << std::endl;
      return 0;
      }

    • 场景: 简化对复合类型成员的访问。
    • 提升: 代码极简,可读性强。
  • if constexpr

    • 新特性: if constexpr (编译期条件) { … } else { … }
    • 使用方法: 在模板中根据类型特性选择性编译代码块。#include <iostream>
      #include <string>
      #include <type_traits> // for is_integral_v, is_same_v

      template <typename T>
      void print_value(T value) {
      if constexpr (std::is_integral_v<T>) {
      std::cout << "Integral: " << value << std::endl;
      } else if constexpr (std::is_same_v<T, std::string>) {
      std::cout << "String: \\"" << value << "\\"" << std::endl;
      } else {
      std::cout << "Other type: " << value << std::endl;
      }
      }

      int main() {
      print_value(10); // 输出 Integral: 10
      print_value("hello"); // 输出 Other type: hello (const char*)
      print_value(std::string("world")); // 输出 String: "world"
      print_value(3.14); // 输出 Other type: 3.14
      return 0;
      }

    • 场景: 模板元编程,替代 SFINAE/标签分发。
    • 提升: 极大简化编译期条件代码。
  • 类模板参数推导 (CTAD)

    • 新特性: std::pair p(1, "hello");
    • 使用方法: 创建模板类对象时省略模板参数。需要构造函数支持或提供推导指引 (deduction guide)。#include <vector>
      #include <string>
      #include <mutex> // for lock_guard

      int main() {
      std::vector v = {1.0, 2.5, 3.0}; // 推导出 std::vector<double>
      std::pair data("key", 100); // 推导出 std::pair<const char*, int>
      std::mutex mtx;
      std::lock_guard lock(mtx); // 推导出 std::lock_guard<std::mutex>
      return 0;
      }

    • 场景: 简化模板对象创建。
    • 提升: 代码更简洁。
  • 标准库“三件套”:std::optional, std::variant, std::any

    • 新库特性: 处理可选值、和类型、任意类型。
    • 使用方法:#include <optional>
      #include <variant>
      #include <any>
      #include <string>
      #include <iostream>

      std::optional<int> maybe_get_int(bool success) {
      if (success) return 42;
      else return std::nullopt; // 表示不存在
      }

      struct Visitor { // 用于 variant
      void operator()(int i) { std::cout << "It's an int: " << i; }
      void operator()(const std::string& s) { std::cout << "It's a string: " << s; }
      void operator()(double d) { std::cout << "It's a double: " << d; }
      };

      int main() {
      // optional
      if (auto val = maybe_get_int(true); val.has_value()) { // 或直接 if(val)
      std::cout << "Optional value: " << val.value() << std::endl; // 或 *val
      }

      // variant
      std::variant<int, std::string, double> my_variant;
      my_variant = "hello";
      std::visit(Visitor{}, my_variant); // 输出 It's a string: hello
      std::cout << std::endl;
      my_variant = 123;
      // C++20 lambda visitor: std::visit([](auto&& arg){ … }, my_variant);

      // any
      std::any anything;
      anything = 10;
      std::cout << "Any holds int: " << std::any_cast<int>(anything) << std::endl;
      try {
      std::cout << std::any_cast<std::string>(anything); // 抛出 std::bad_any_cast
      } catch (const std::bad_any_cast& e) {
      std::cout << "Bad any_cast: " << e.what() << std::endl;
      }
      return 0;
      }

    • 场景: 函数返回值、状态表示、存储异构数据。
    • 提升: 类型安全、代码意图清晰。
  • std::string_view

    • 新库特性: 非拥有性的字符串引用。
    • 使用方法: 接收 const char*, std::string 等作为参数,进行只读操作。#include <string_view>
      #include <iostream>

      void print_substring(std::string_view sv) {
      std::cout << "Substring: [" << sv << "]\\n";
      }

      int main() {
      std::string long_str = "This is a rather long string";
      std::string_view view(long_str);

      print_substring(view.substr(5, 7)); // 高效创建子串视图 "is a ra"
      print_substring("A C-style literal"); // 直接从字面量创建
      return 0;
      }

    • 场景: 处理只读字符串,特别是函数参数,避免不必要的拷贝。
    • 提升: 性能,减少内存分配。
  • 并行算法

    • 新库特性: std::sort(std::execution::par, …)
    • 使用方法: 为 STL 算法提供执行策略参数 (seq, par, par_unseq)。
    • 场景: 加速大规模数据处理。
    • 提升: 标准化的并行加速入口。需要编译器和库支持,可能需要链接特定库(如 TBB)。
  • 文件系统库 (<filesystem>)

    • 新库特性: 跨平台文件操作。
    • 使用方法: fs::path, fs::exists, fs::is_directory, fs::create_directory, fs::remove 等。#include <filesystem>
      #include <iostream>
      namespace fs = std::filesystem;

      int main() {
      fs::path current = fs::current_path();
      fs::path new_dir = current / "my_test_dir";
      fs::create_directory(new_dir);
      std::cout << "Directory created: " << new_dir << std::endl;
      fs::remove(new_dir);
      std::cout << "Directory removed." << std::endl;
      return 0;
      }

    • 场景: 文件、目录管理。
    • 提升: 标准化、可移植的文件系统操作。
  • C++20:再次飞跃 —— 引入基础性变革

    (发布于 2020年)

    C++20 是又一个引入颠覆性特性的大版本,显著改变了泛型编程、异步编程和代码组织方式。

    主要新特性详解 (重点“四大特性”):

  • 概念 (Concepts)

    • 新语言特性: concept, requires 关键字。
    • 使用方法: 定义类型约束,并在模板声明中使用。#include <concepts>
      #include <vector>
      #include <iostream>

      template<typename T>
      concept Incrementable = requires(T x) { ++x; x++; }; // 要求支持前置和后置自增

      template<Incrementable T> // 约束 T 必须满足 Incrementable
      void increment_twice(T& value) {
      ++value;
      value++;
      }

      struct NonIncrementable {};

      int main() {
      int i = 0;
      increment_twice(i); // OK, int 满足
      std::cout << i << std::endl; // 输出 2

      double d = 1.0;
      increment_twice(d); // OK, double 满足
      std::cout << d << std::endl; // 输出 3.0

      // NonIncrementable ni;
      // increment_twice(ni); // 编译错误!不满足 Incrementable 概念
      return 0;
      }

    • 场景: 模板编程,提高类型约束的清晰度和编译错误友好性。
    • 提升: 革命性改善模板编程体验。
  • 模块 (Modules)

    • 新语言特性: export module, import。
    • 使用方法: 定义模块接口 (.cppm 实验性) 和实现,使用 import 导入。// —- my_module.cppm (假设) —-
      export module my_module;
      export int add(int x, int y) { return x + y; }
      // —- main.cpp (假设) —-
      import my_module;
      int main() { return add(2, 3); }
    • 场景: 大型项目代码组织。
    • 提升(理论): 编译速度、封装性、消除宏污染。依赖工具链支持。
  • 协程 (Coroutines)

    • 新语言特性: co_await, co_yield, co_return。
    • 使用方法: 定义协程函数(返回特定类型,如 generator, task),使用 co_ 关键字实现暂停/恢复。#include <iostream>
      #include <coroutine> // 低层支持
      // #include <generator> // C++23 标准库,或使用第三方库

      // (需要一个 generator 实现,这里是伪代码)
      /*
      generator<int> count_upto(int n) {
      for (int i = 0; i < n; ++i) {
      co_yield i; // 产生值并暂停
      }
      }
      int main() {
      for(int x : count_upto(5)) { // 每次循环恢复协程
      std::cout << x << " "; // 输出 0 1 2 3 4
      }
      std::cout << std::endl;
      return 0;
      }
      */

      int main() {
      std::cout << "C++20 Coroutines need library support.\\n";
      return 0;
      }

    • 场景: 异步编程、生成器、状态机。
    • 提升: 用同步风格编写异步代码,简化复杂流程。依赖库支持。
  • 范围库 (Ranges)

    • 新库特性: <ranges>, std::views, 范围版算法。
    • 使用方法: 对容器直接调用算法,用 | 组合视图。#include <vector>
      #include <ranges>
      #include <iostream>
      #include <algorithm> // for std::ranges::sort

      namespace views = std::views;
      namespace ranges = std::ranges;

      int main() {
      std::vector<int> data = {1, 8, 2, 7, 3, 6, 4, 5};

      auto query = data | views::filter([](int n){ return n > 3; })
      | views::transform([](int n){ return n * n; })
      | views::take(3); // 取前 3 个结果

      std::cout << "Query results: ";
      for(int x : query) { // 惰性求值
      std::cout << x << " "; // 输出 64 49 36
      }
      std::cout << std::endl;

      // 范围版排序
      ranges::sort(data);
      std::cout << "Sorted data: ";
      for(int x : data) std::cout << x << " ";
      std::cout << std::endl;

      return 0;
      }

    • 场景: 数据处理流水线,简化算法调用。
    • 提升: 声明式数据处理,代码更简洁、可读性强,惰性求值可能带来性能优势。
  • C++20 其他重要特性:

    • 三路比较运算符 (<=>): auto result = obj1 <=> obj2;
    • constexpr 增强: 编译期 vector 和 string 成为可能。
    • 格式化库 (<format>): std::string s = std::format("Hello, {}! Count: {}", "world", 42);
    • <span>: void process(std::span<const int> data);
    • jthread: std::jthread t(func); // 析构时自动 join

    C++23 及未来:持续前行

    (C++23 已发布)

    C++23 继续带来改进,例如:

    • std::expected: std::expected<int, ErrorCode> func();
    • std::print: std::print("Value: {}\\n", 42);
    • Ranges 增强: 更多视图和算法。
    • 模块改进。
    • if consteval: 编译期执行的 if。
    • mdspan: 多维数组视图。
    • move_only_function: 只能移动的函数包装器。

    C++26 也在稳步推进中,未来可期!

    结语:成为现代 C++ 开发者

    C++ 的进化是一部精彩的技术演进史。现代 C++ 通过引入一系列强大的语言和库特性,极大地改善了开发体验、代码安全性和程序性能。

    从 C++11 的智能指针、Lambda、auto,到 C++14 的完善,再到 C++17 的可用性飞跃,以及 C++20 的四大核心变革,每一个版本都值得我们去学习和应用。

    拥抱现代 C++,意味着用更少的代码做更多的事,写出更安全、更高效、更易于维护的程序。无论你的 C++ 之旅处于哪个阶段,持续学习和实践这些新特性,都将让你在这座不断成长的“编程摩天楼”里更加游刃有余。


    赞(0)
    未经允许不得转载:网硕互联帮助中心 » C++ 的史诗级进化:从C++98到C++20
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!