C++20 Rangesライブラリ入門
イテレーターのペアではなく範囲を受け取るstd::rangesアルゴリズムを使います。
「C++20 Rangesライブラリ入門」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。
Ranges を使う理由
従来の STL では、イテレータのペア(v.begin(), v.end())を渡します。C++20 の ranges では、単一の range 値を渡せ、合成も可能です。
Ranges のインクルード
<ranges> をインクルードします。アルゴリズムには std::ranges、遅延ビューには std::views の名前空間を使用します。
#include <ranges>
#include <algorithm>Range アルゴリズム
標準アルゴリズムにはすべて、2つのイテレータの代わりに範囲を受け取る ranges 版があります。
std::vector<int> v = {3, 1, 4, 1, 5};
std::ranges::sort(v); // sort the whole range
auto it = std::ranges::find(v, 4);射影関数
Range アルゴリズムは、任意の projection(各要素に対して比較前に適用する関数)を受け取れます。これにより、カスタム比較関数を記述せずに済みます。
struct Person { std::string name; int age; };
std::vector<Person> people;
std::ranges::sort(people, {}, &Person::age);
// sort by age, default comparisonRange とは
range とは、begin() と end() をサポートするあらゆるものです。コンテナや配列に加え、C++20 ではセンチネルを公開するカスタム型も該当します。
センチネル
C++20 では、end() を sentinel(センチネル)へと一般化しました。センチネルはイテレータと同じ型である必要がありません。入力ストリームや無限範囲に便利です。
ビュー:遅延範囲パイプライン
view は要素を必要に応じて生成する、所有権を持たない範囲です。パイプ演算子 | で合成できます。
auto squares = v
| std::views::filter([](int x) { return x % 2 == 0; })
| std::views::transform([](int x) { return x * x; });
for (int x : squares) std::cout << x << " ";遅延評価
ビューは反復されるまで、メモリを確保せず、処理も実行しません。filter | transform | take(5) は変換後の最初の5個の値だけを生成し、それ以上は生成しません。
借用範囲とライフタイム
ビューは元の範囲を借用します。元の範囲が破棄されると、ビューはダングリング状態になります。一時オブジェクトに対するビューには注意が必要ですが、C++20 では安全対策が追加されています。
Eager と Lazy
アルゴリズムは結果を即座に生成します(その場で計算します)。ビューは遅延評価されます(反復時に計算します)。結果を実体化する必要があるかどうかに応じて選択してください。
パフォーマンス
遅延パイプラインを使うと、中間コンテナを回避できます。コンパイラーは多くの場合、パイプラインを単一のループであるかのように最適化します。確認するには godbolt で調べてください。
移行への道筋
C++20 を使用できない場合は、Eric Niebler の range-v3 のようなライブラリによって、C++14/17 でも同じモデルを利用できます。将来の移行を容易にするため、今のうちに学んでおく価値があります。
理解度チェック
C++20 の ranges が、イテレータペアを使う従来の STL スタイルより優れている主な点は何ですか。
まとめ
C++20 の ranges は STL アルゴリズムを現代化します。単一の範囲を渡し、射影を使用し、ビューによる遅延パイプラインを構築できます。パイプ演算子を使うと、filter、transform、take を組み合わせて、明確で宣言的なコードを記述できます。
よくある質問
「C++20 Rangesライブラリ入門」レッスンは無料ですか?
はい。「C++20 Rangesライブラリ入門」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。
「C++20 Rangesライブラリ入門」で何を学びますか?
イテレーターのペアではなく範囲を受け取るstd::rangesアルゴリズムを使います。 ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C++ Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「C++20 Rangesライブラリ入門」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC++ Academyレッスンでコードを書いて実行できますか?
はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- イテレーターカテゴリー:input、forward、bidirectional、random
- イテレーターの一般的なパターン:begin、end、advance
- C++20 Rangesライブラリ入門
- 範囲アダプター:views::filter、transform、take