C++ 23 标准:协程、反射与新特性综述

C++ 23 标准作为 C++ 20 的后续版本,在保持语言稳定性的同时,进一步丰富了语言本身的功能。本文将重点讨论其中最具代表性的新增特性——协程(Coroutines)、编译时反射(Compile-Time Reflection)以及其他实用功能,并给出简单示例帮助读者快速上手。

1. 协程(Coroutines)新语法

C++ 23 对协程的支持进一步完善,除了之前的 co_yieldco_return,新增了更易用的 std::suspend_alwaysstd::suspend_never,以及统一的 std::generator。示例:

#include <iostream>
#include <coroutine>

template<typename T>
struct generator {
    struct promise_type {
        T current_value;
        std::suspend_always yield_value(T value) {
            current_value = value;
            return {};
        }
        std::suspend_always initial_suspend() noexcept { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        generator get_return_object() {
            return generator{ std::coroutine_handle <promise_type>::from_promise(*this) };
        }
        void unhandled_exception() { std::exit(1); }
        void return_void() {}
    };

    std::coroutine_handle <promise_type> handle;
    generator(std::coroutine_handle <promise_type> h) : handle(h) {}
    ~generator() { if (handle) handle.destroy(); }

    T next() {
        handle.resume();
        return handle.promise().current_value;
    }
};

generator <int> count_to_five() {
    for (int i = 1; i <= 5; ++i)
        co_yield i;
}

int main() {
    auto gen = count_to_five();
    for (int i = 0; i < 5; ++i)
        std::cout << gen.next() << " ";
    // 输出:1 2 3 4 5
}

协程让我们能够以异步或惰性计算的方式编写代码,显著提升可读性和性能。

2. 编译时反射(Compile-Time Reflection)

C++ 23 引入了 std::reflect(尚未正式标准化,但已在最新编译器实现中可用)。反射允许在编译期获取类型信息,例如成员变量名、类型、可访问性。示例:

#include <iostream>
#include <reflect>

struct Person {
    std::string name;
    int age;
};

int main() {
    for (auto&& [name, type] : std::reflect <Person>) {
        std::cout << name << " : " << type << '\n';
    }
}

输出:

name : std::string
age : int

这使得泛型编程更加灵活,能够在编译期做更多检查,减少运行时开销。

3. 其他实用特性

3.1 std::expected

std::expected 类似于 Result 类型,提供错误与成功的统一包装,减少异常开销。示例:

#include <expected>
#include <string>

std::expected<int, std::string> divide(int a, int b) {
    if (b == 0) return std::unexpected("division by zero");
    return a / b;
}

int main() {
    auto res = divide(10, 0);
    if (res) std::cout << *res << '\n';
    else std::cerr << res.error() << '\n';
}

3.2 std::array::operator[] 支持范围检查

在 C++ 23 中,std::arrayoperator[] 可以返回 std::span,实现更安全的范围操作。

3.3 std::format 的改进

支持自定义格式化字符串,类似 Python 的 f-string,提高日志输出与字符串拼接效率。

4. 如何在项目中使用 C++ 23

  1. 编译器:确保使用支持 C++ 23 的编译器版本,例如 GCC 13+、Clang 15+、MSVC 19.34+。
  2. 构建系统:在 CMake 项目中添加 set(CMAKE_CXX_STANDARD 23) 或者使用 -std=c++23 标志。
  3. 依赖管理:若使用第三方库,检查其是否已兼容 C++ 23,或者使用适配层。

5. 小结

C++ 23 通过协程、编译时反射以及诸多实用特性,进一步提升了语言的表达力与性能。熟练掌握这些新特性,将帮助开发者编写更高效、更安全、更易维护的 C++ 代码。希望本文能为你开启探索 C++ 23 的旅程。

发表评论