# C++20 的范围-based for 与 ranges 库:实现自定义视图

在 C++20 之后,<ranges> 库正式进入标准,提供了比传统迭代器更高层次、更函数式的容器操作方式。借助 ranges::view,我们可以在不显式写循环的情况下对容器进行切片、过滤、映射等操作。本文将以实现一个自定义“平方数视图”为例,演示如何利用 ranges 进行流式编程,并解释其内部工作原理。

1. 背景:传统的 for 循环 vs 范围

传统的 for 循环(基于下标或迭代器)需要手动管理索引、终止条件以及访问方式,代码往往显得冗长且易出错。相比之下,范围(range)概念把容器视为“可遍历的元素序列”,并通过视图(view)对其进行变换。一个视图本质上是对原始容器的一种惰性、按需计算的包装,而不产生中间副本。

2. 关键概念

关键词 含义
view 对容器进行惰性变换的适配器,例如 filter, transform, take, drop
ranges::range 一个类型概念,表示能被 begin/end 迭代的对象
borrowed_view 只读视图,生命周期与底层容器相同
view::all 将任意范围包装为 borrowed_view,即默认视图

3. 实现平方数视图

我们要做的是:给定一个整数范围 `std::vector

`,生成一个视图,仅保留偶数元素,并将每个元素映射为其平方值。使用 `ranges`,实现过程如下: “`cpp #include #include #include #include namespace rv = std::ranges; namespace rvf = std::ranges::views; // 1. 创建一个自定义视图:偶数过滤 + 平方映射 auto even_square_view(const std::vector & vec) { // 通过 `rvf::filter` 保留偶数,然后 `rvf::transform` 平方 auto filtered = vec | rvf::filter([](int x){ return x % 2 == 0; }); auto squared = filtered | rvf::transform([](int x){ return x * x; }); return squared; // 返回一个视图 } int main() { std::vector numbers{1,2,3,4,5,6,7,8}; // 2. 直接使用范围-based for 遍历视图 std::cout (std::cout, ” “)); std::cout

发表评论