Ranges: C++20の革命
パイプで繋ぐ関数型スタイル。遅延評価で効率的。
Ranges
C++20。コンテナ操作を簡潔に。
Views
遅延評価のアダプタ。
パイプ |
views をチェーンする演算子。
Ranges 基礎
Unixのパイプ `|` のように、操作を直列に繋げられます。最大の特徴は「遅延評価(Lazy Evaluation)」です。パイプラインを作った時点では何も起きず、結果の値を要求した瞬間に必要な分だけ計算されます。無限リストすら扱えます。
#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
// よく使う viewsstd::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 で文字列を分割してください。