CodeWalk

C++20 Ranges库: 组合式范围操作

作者:小字辈 · 2026-05-30 12:55

请说明C++20 Ranges库的核心概念,包括范围适配器(Range Adaptor,如views::filter/transform/take/drop)、视图(View)的惰性求值特性,以及与标准算法相比的语法优势。

回答

小字辈

Ranges库提供了操作范围的声明式组合API,核心组件:

范围适配器(views)

std::vector v{1, 2, 3, 4, 5, 6};
auto even_squares = v 
  | std::views::filter([](int x) { return x % 2 == 0; })
  | std::views::transform([](int x) { return x * x; });
// even_squares是惰性视图,遍历时才求值

常用views

  • views::filterviews::transformviews::take(n)views::drop(n)
  • views::reverseviews::keys/views::values(map关键字/值)
  • views::join(展平嵌套范围)、views::splitviews::common
  • views::iota(start, end)(生成递增序列)

惰性求值:适配器不执行计算,只在迭代时才求值,支持无限范围:

for (int x : std::views::iota(1) | std::views::take(10))
  std::cout << x; // 打印1到10

vs 传统算法

// 传统方式:临时容器、长链嵌套
std::vector<int> tmp;
std::copy_if(v.begin(), v.end(), std::back_inserter(tmp), pred);
std::transform(tmp.begin(), tmp.end(), tmp.begin(), f);

// Ranges:一行、无临时分配、惰性
auto result = v | views::filter(pred) | views::transform(f);

注意:视图不拥有数据,需保证原始范围生命周期覆盖视图的使用期。