C++20 中的 std::ranges 与传统算法的融合

在 C++20 中引入的 库为容器和算法提供了一种更为直观和安全的组合方式。相比传统的基于迭代器的算法调用,ranges 采用的是 viewpipeable 的概念,使代码既简洁又易于组合。本文将从两个方面来说明如何在实际项目中将 ranges 与传统算法相结合,以及它们之间的优势与注意事项。


1. ranges 基础概念回顾

1.1 View

  • View:一种延迟评估的序列,表示对原始容器的一种视图(如切片、去重、筛选等)。常见的 view 有 std::views::filterstd::views::transformstd::views::takestd::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

发表评论