在 C++20 里,std::ranges 为容器操作带来了极大的便利,让代码既简洁又易读。下面通过一个完整的例子,演示如何利用 std::ranges::filter, std::ranges::transform, std::ranges::to 等工具,对 std::vector<int> 进行筛选、变换,并最终得到结果容器。
#include <iostream>
#include <vector>
#include <ranges>
#include <algorithm>
int main() {
// 原始数据
std::vector <int> data{1, 2, 3, 4, 5, 6, 7, 8};
// 1. 先筛选出偶数
auto even_filter = std::ranges::views::filter([](int n){ return n % 2 == 0; });
// 2. 对偶数进行平方
auto square_transform = std::ranges::views::transform([](int n){ return n * n; });
// 3. 组合视图
auto processed = data | even_filter | square_transform;
// 4. 收集结果到 vector
std::vector <int> result;
result = processed | std::ranges::to<std::vector>();
// 打印结果
std::cout << "偶数的平方: ";
for (auto v : result)
std::cout << v << ' ';
std::cout << '\n';
return 0;
}
关键点说明
-
views::filter
接收一个谓词,返回一个延迟求值的视图。只有当你遍历视图时,才会真正调用谓词,极大节省了中间容器的创建。 -
views::transform
类似于std::transform,但返回的是一个视图,支持链式组合。这里用它来计算平方。 -
管道操作符 (
|)
C++20 为容器视图提供了管道语法,使得链式调用更像 DSL,代码更直观。 -
ranges::to
用来把视图“收集”到目标容器。std::ranges::to<std::vector>()会创建并返回一个std::vector,内容为视图中的元素。
性能优势
- 无中间临时容器:
filter与transform组合后,元素在一次遍历中完成筛选与变换,无需为中间结果创建额外容器。 - 按需求值:视图是惰性的,只有真正需要访问元素时才会触发计算。
- 可组合性:视图可以无缝组合成更复杂的处理链,代码易于维护。
小结
C++20 的 std::ranges 为容器操作提供了一种更接近函数式编程的方式。通过视图组合、惰性求值与直观的管道语法,你可以轻松实现复杂的数据处理逻辑,同时保持代码简洁、可读且高效。希望本文能帮助你快速上手 std::ranges,并在实际项目中发挥其优势。