**C++20 新特性全景:范围视图、协程与概念**

C++20 是 C++ 语言家族的一次重大升级,新增了许多功能来提高语言的表达力、简化代码以及提升性能。本文将重点介绍三大新特性:范围视图(Ranges Views)、协程(Coroutines)以及概念(Concepts),并给出每个特性的基本用法与常见场景。


1. 范围视图(Ranges Views)

1.1 背景

传统的 STL 迭代器模式需要手动编写循环或使用 std::transformstd::accumulate 等算法,代码冗长且不易阅读。C++20 的 std::ranges 提供了一套函数式的视图(view)和适配器(adapter),可以链式组合,形成不可变的“惰性序列”。

1.2 基本语法

#include <ranges>
#include <vector>
#include <iostream>

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

    auto even = std::views::filter([](int n){ return n % 2 == 0; });
    auto squared = std::views::transform([](int n){ return n * n; });

    for (int n : vec | even | squared) {
        std::cout << n << ' ';  // 4 16 36 64 100
    }
}

1.3 常用视图

视图 作用 示例
std::views::filter 根据谓词过滤元素 vec | std::views::filter(is_prime)
std::views::transform 对每个元素应用函数 vec | std::views::transform([](auto x){ return x * 2; })
std::views::take 截取前 N 个元素 vec | std::views::take(5)
std::views::drop 跳过前 N 个元素 vec | std::views::drop(3)
std::views::reverse 逆序 vec | std::views::reverse

2. 协程(Coroutines)

2.1 背景

协程使得异步编程变得更直观、可读。传统的回调或状态机模式容易导致“回调地狱”。C++20 的协程提供了 co_awaitco_yieldco_return 关键字,支持暂停与恢复。

2.2 简单生成器

#include <coroutine>
#include <iostream>

struct Generator {
    struct promise_type;
    using handle_type = std::coroutine_handle <promise_type>;
    struct promise_type {
        int value_;
        Generator get_return_object() {
            return Generator{handle_type::from_promise(*this)};
        }
        std::suspend_always initial_suspend() { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        std::suspend_always yield_value(int v) {
            value_ = v;
            return {};
        }
        void return_void() {}
        void unhandled_exception() { std::terminate(); }
    };
    handle_type coro_;
    Generator(handle_type h) : coro_(h) {}
    ~Generator() { coro_.destroy(); }
    bool next() { return coro_.resume(); }
    int value() const { return coro_.promise().value_; }
};

Generator range(int start, int end) {
    for (int i = start; i <= end; ++i)
        co_yield i;
}

int main() {
    auto gen = range(1, 5);
    while (gen.next()) {
        std::cout << gen.value() << ' '; // 1 2 3 4 5
    }
}

2.3 应用场景

  • 异步 I/O(如网络请求、文件读取)
  • 数据流(可按需产生)
  • 迭代器的简化实现

3. 概念(Concepts)

3.1 背景

模板编程经常出现“模板雾”问题:错误信息难以理解、未满足约束导致编译报错。概念为模板参数添加了语义层,能够在编译时对类型进行检查,并给出友好的错误提示。

3.2 定义与使用

#include <concepts>
#include <iostream>

template <typename T>
concept Incrementable = requires(T x) {
    { ++x } -> std::same_as<T&>;
    { x++ } -> std::same_as <T>;
};

template <Incrementable T>
void increment(T& t) {
    ++t;
}

int main() {
    int a = 5;
    increment(a); // 6
}

3.3 典型概念

名称 说明
std::integral 整数类型
std::floating_point 浮点类型
std::ranges::range 范围类型
`std::same_as
| 与T` 同类型
`std::derived_from
| 继承自B`

4. 小结

  • 范围视图:让序列处理更加声明式,减少样板代码。
  • 协程:提供简洁的异步编程模型,天然支持惰性求值。
  • 概念:提升模板代码的可读性与错误可诊断性。

这三大新特性共同推动 C++ 向更安全、更高效、更易用的方向发展。掌握它们后,你将能写出更现代、更符合现代软件工程要求的 C++ 代码。祝你编码愉快!


发表评论