Ranges: C++20の革命

パイプで繋ぐ関数型スタイル。遅延評価で効率的。

Ranges
C++20。コンテナ操作を簡潔に。
Views
遅延評価のアダプタ。
パイプ |
views をチェーンする演算子。

Ranges 基礎

工場のベルトコンベア (Pipeline)

Rangesは「ベルトコンベア」です。データ(原材料)がパイプラインを流れ、フィルタ(選別機)や変換(加工機)を通って、最終製品になります。従来のように工程ごとに箱(一時配列)に詰める必要はなく、データはスムーズに流れます。

Unixのパイプ `|` のように、操作を直列に繋げられます。最大の特徴は「遅延評価(Lazy Evaluation)」です。パイプラインを作った時点では何も起きず、結果の値を要求した瞬間に必要な分だけ計算されます。無限リストすら扱えます。

Ranges with Pipe
#include <ranges>
#include <vector>
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// パイプ演算子でチェーン
auto result = v
| std::views::filter([](int n) { return n % 2 == 0; })
| std::views::transform([](int n) { return n * n; })
| std::views::take(3);
// result: 4, 16, 36(遅延評価)
for (int n : result) {
std::cout << n << " ";
}
実行結果
filter(偶数) → {2,4,6,8,10}
transform(*2) → {4,16,36}
take(3) → 4 16 36
Bad
// ❌ Bad: 中間コンテナが必要
std::vector<int> temp;
std::copy_if(v.begin(), v.end(), ...);
std::transform(temp.begin(), ...);
Good
// ✅ Good: Ranges でパイプ
auto result = v
| std::views::filter(pred)
| std::views::transform(fn);

Views

Common Views
// よく使う views
std::views::filter(pred) // 条件に合うもの
std::views::transform(fn) // 変換
std::views::take(n) // 最初のn個
std::views::drop(n) // 最初のn個をスキップ
std::views::reverse // 逆順
std::views::keys // mapのキー
std::views::values // mapの値
std::views::iota(1, 10) // 1〜9を生成
// 範囲生成
for (int i : std::views::iota(1, 10)) {
std::cout << i << " "; // 1 2 3 ... 9
}
// split (C++23)
// std::views::split("a,b,c", ',')
Tip: views は遅延評価。必要な分だけ計算される。

合格ライン

パイプで views をチェーンできる
filter/transform/take を使える

参考リンク

演習課題

課題1: パイプライン
filter | transform | take のパイプラインを作成してください。
課題2: views::split
views::split で文字列を分割してください。

次のステップ