在 C++20 中引入的 库为容器和算法提供了一种更为直观和安全的组合方式。相比传统的基于迭代器的算法调用,ranges 采用的是 view 与 pipeable 的概念,使代码既简洁又易于组合。本文将从两个方面来说明如何在实际项目中将 ranges 与传统算法相结合,以及它们之间的优势与注意事项。
1. ranges 基础概念回顾
1.1 View
- View:一种延迟评估的序列,表示对原始容器的一种视图(如切片、去重、筛选等)。常见的 view 有
std::views::filter、std::views::transform、std::views::take、std::views::reverse等。 - View 的优点是无副作用:它们不复制数据,而是根据需要动态生成元素,适合大数据量处理。
1.2 Pipeable 算法
- Pipeable:算法可以像函数链一样被“管道化”使用,语法类似
std::views::filter(...) | std::views::transform(...) | std::ranges::for_each(...)。 - 与传统算法的差别在于,pipeable 算法使用 范围 作为输入,而非迭代器对。
2. 传统算法示例
假设我们有一个 `std::vector
`,需要先筛选偶数,再乘以 2,最后统计其和。 “`cpp std::vector vec = {1,2,3,4,5,6,7,8,9,10}; int sum = 0; std::for_each( std::make_move_iterator(vec.begin()), std::make_move_iterator(vec.end()), [&sum](int x) { if (x % 2 == 0) sum += x * 2; }); “` 上述代码虽然可行,但可读性不高,且存在多次遍历的隐式成本。 — ## 3. ranges 版实现 “`cpp #include #include #include #include int main() { std::vector vec{1,2,3,4,5,6,7,8,9,10}; int sum = std::ranges::fold_left( vec | std::views::filter([](int n){ return n % 2 == 0; }) | std::views::transform([](int n){ return n * 2; }), 0, std::plus() ); std::cout