Rangesライブラリ (C++20以降)
Rangeライブラリは、アルゴリズムライブラリとイテレータライブラリを拡張および一般化したものであり、組み合わせ可能でエラーを起こしにくくすることで、より強力なものにします。
このライブラリは、反復可能なシーケンス(range)を間接的に表現する軽量なオブジェクトであるrange viewを生成・操作します。Rangeは、以下のものの上位にある抽象化です。
-
[begin,end)– イテレータのペア、例: コンテナからの暗黙の変換によって作られるrange。イテレータのペアを受け取るすべてのアルゴリズムには、rangeを受け取るオーバーロードが追加されました (例: ranges::sort)。 - begin
+[0,size)– カウントされるシーケンス、例: views::counted が返すrange。 -
[begin,predicate)– 条件付きで終端するシーケンス、例: views::take_while が返すrange。 -
[begin,..)– 無限シーケンス、例: views::iota が返すrange。
Rangeライブラリには、rangeに先行評価で適用されるrangeアルゴリズムと、viewに遅延評価で適用されるrangeアダプタが含まれます。アダプタはパイプラインに構成することができ、そのアクションはviewが反復されるときに実行されます。
| ヘッダ <ranges> で定義 |
||
| namespace std { namespace views = ranges::views; |
(C++20以降) | |
名前空間エイリアス std::views は std::ranges::views の短縮形として提供されます。
| 名前空間
std::ranges で定義 | ||
Rangeアクセス | ||
| ヘッダ
<ranges> で定義 | ||
| ヘッダ
<iterator> で定義 | ||
| (C++20) |
rangeの先頭を指すイテレータを返す (カスタマイゼーションポイントオブジェクト) | |
| (C++20) |
rangeの終端を示す番兵を返す (カスタマイゼーションポイントオブジェクト) | |
| (C++20) |
読み取り専用rangeの先頭を指すイテレータを返す (カスタマイゼーションポイントオブジェクト) | |
| (C++20) |
読み取り専用rangeの終端を示す番兵を返す (カスタマイゼーションポイントオブジェクト) | |
| (C++20) |
rangeへの逆イテレータを返す (カスタマイゼーションポイントオブジェクト) | |
| (C++20) |
rangeへの逆終端イテレータを返す (カスタマイゼーションポイントオブジェクト) | |
| (C++20) |
読み取り専用rangeへの逆イテレータを返す (カスタマイゼーションポイントオブジェクト) | |
| (C++20) |
読み取り専用rangeへの逆終端イテレータを返す (カスタマイゼーションポイントオブジェクト) | |
| (C++26) |
rangeによって与えられる予約ヒントと等しい整数を返す (カスタマイゼーションポイントオブジェクト) | |
| (C++20) |
rangeのサイズと等しい整数を返す (カスタマイゼーションポイントオブジェクト) | |
| (C++20) |
rangeのサイズと等しい符号付き整数を返す (カスタマイゼーションポイントオブジェクト) | |
| (C++20) |
rangeが空かどうかをチェックする (カスタマイゼーションポイントオブジェクト) | |
| (C++20) |
連続rangeの先頭へのポインタを取得する (カスタマイゼーションポイントオブジェクト) | |
| (C++20) |
読み取り専用の連続rangeの先頭へのポインタを取得する (カスタマイゼーションポイントオブジェクト) | |
Rangeプリミティブ | ||
| ヘッダ
<ranges> で定義 | ||
| (C++20)(C++23)(C++20)(C++23) |
rangeのイテレータ型と番兵型を取得する (エイリアステンプレート) | |
| (C++20)(C++20)(C++20) |
rangeのサイズ型、差分型、値型を取得する (エイリアステンプレート) | |
| rangeの参照型を取得する (エイリアステンプレート) | ||
ダングリングイテレータの扱い | ||
| ヘッダ
<ranges> で定義 | ||
| (C++20) |
イテレータや subrange がダングリングになるため返されるべきでないことを示すプレースホルダー型(クラス) | |
borrowed_range のイテレータ型または subrange 型を取得する(エイリアステンプレート) | ||
その他のユーティリティ | ||
| ヘッダ
<ranges> で定義 | ||
| (C++23) |
rangeを単一の値ではなくシーケンスとして扱うようにタグ付けする (クラステンプレート) | |
Rangeコンセプト | ||
| ヘッダ
<ranges> で定義 | ||
| (C++20) |
型がrangeであること、すなわち begin イテレータと end 番兵を提供することを規定する(コンセプト) | |
| (C++20) |
型がrangeであり、その式のインスタンスから取得したイテレータがダングリングの危険なく安全に返されることを規定する(コンセプト) | |
| rangeが定数時間でそのサイズを推定できることを規定する (コンセプト) | ||
| (C++20) |
rangeが定数時間でそのサイズを知っていることを規定する (コンセプト) | |
| (C++20) |
rangeがviewであること、すなわち定数時間でのコピー/ムーブ/代入を持つことを規定する (コンセプト) | |
| (C++20) |
イテレータ型が input_iterator を満たすrangeを規定する(コンセプト) | |
| (C++20) |
イテレータ型が output_iterator を満たすrangeを規定する(コンセプト) | |
| (C++20) |
イテレータ型が forward_iterator を満たすrangeを規定する(コンセプト) | |
| (C++20) |
イテレータ型が bidirectional_iterator を満たすrangeを規定する(コンセプト) | |
| (C++20) |
イテレータ型が random_access_iterator を満たすrangeを規定する(コンセプト) | |
| (C++20) |
イテレータ型が contiguous_iterator を満たすrangeを規定する(コンセプト) | |
| (C++20) |
rangeが同一のイテレータ型と番兵型を持つことを規定する (コンセプト) | |
| (C++20) |
range が view に安全に変換できるための要件を規定する(コンセプト) | |
| (C++23) |
rangeが読み取り専用の要素を持つことを規定する (コンセプト) | |
Range変換 | ||
| ヘッダ
<ranges> で定義 | ||
| (C++23) |
入力rangeから新しい非viewオブジェクトを構築する (関数テンプレート) | |
表示 | ||
| ヘッダ
<ranges> で定義 | ||
| (C++20) |
CRTP (Curiously Recurring Template Pattern) を使用してviewを定義するためのヘルパークラステンプレート(クラステンプレート) | |
| (C++20) |
イテレータと番兵のペアをviewに結合する(クラステンプレート) | |
[編集] Rangeファクトリ
| ヘッダ
<ranges> で定義 | |
| 名前空間
std::ranges で定義 | |
要素を持たない空の view(クラステンプレート) (変数テンプレート) | |
指定された値の単一要素を含む view(クラステンプレート) (カスタマイゼーションポイントオブジェクト) | |
| (C++20) |
初期値を繰り返しインクリメントして生成されるシーケンスからなる view(クラステンプレート) (カスタマイゼーションポイントオブジェクト) |
同じ値を繰り返し生成することで得られるシーケンスからなる view(クラステンプレート) (カスタマイゼーションポイントオブジェクト) | |
関連付けられた入力ストリームに対して operator>> を連続して適用することで得られる要素からなる view(クラステンプレート) (カスタマイゼーションポイントオブジェクト) | |
[編集] Rangeアダプタ
| ヘッダ
<ranges> で定義 | |
| 名前空間
std::ranges で定義 | |
| rangeアダプタクロージャオブジェクトを定義するためのヘルパー基底クラステンプレート (クラステンプレート) | |
| (C++20) |
rangeのすべての要素を含む view(エイリアステンプレート) (rangeアダプタオブジェクト) |
| (C++20) |
他の何らかのrangeの要素の view(クラステンプレート) |
| (C++20) |
何らかのrangeの唯一の所有権を持つ view(クラステンプレート) |
各要素を右辺値にキャストするシーケンスの view(クラステンプレート) (rangeアダプタオブジェクト) | |
述語を満たすrangeの要素からなる view(クラステンプレート) (rangeアダプタオブジェクト) | |
各要素に変換関数を適用するシーケンスの view(クラステンプレート) (rangeアダプタオブジェクト) | |
| (C++20) |
別のviewの最初のN個の要素からなる view(クラステンプレート) (rangeアダプタオブジェクト) |
別のviewの先頭から、述語がfalseを返す最初の要素までの要素からなる view(クラステンプレート) (rangeアダプタオブジェクト) | |
| (C++20) |
別のviewの要素から、最初のN個の要素をスキップして構成される view(クラステンプレート) (rangeアダプタオブジェクト) |
別のviewの要素から、述語がfalseを返す最初の要素までの先頭部分シーケンスをスキップして構成される view(クラステンプレート) (rangeアダプタオブジェクト) | |
| (C++20) |
rangeのviewをフラット化して得られるシーケンスからなる view(クラステンプレート) (rangeアダプタオブジェクト) |
rangeのviewをフラット化し、要素の間に区切り文字を挟んで得られるシーケンスからなる view(クラステンプレート) (rangeアダプタオブジェクト) | |
別のviewを区切り文字で分割して得られる部分rangeに対する view(クラステンプレート) (rangeアダプタオブジェクト) | |
別のviewを区切り文字で分割して得られる部分rangeに対する view(クラステンプレート) (rangeアダプタオブジェクト) | |
適合するviewを連結して構成される view(クラステンプレート) (カスタマイゼーションポイントオブジェクト) | |
| (C++20) |
イテレータとカウントから部分rangeを作成する (カスタマイゼーションポイントオブジェクト) |
view を common_range に変換する(クラステンプレート) (rangeアダプタオブジェクト) | |
別の双方向viewの要素を逆順に反復処理する view(クラステンプレート) (rangeアダプタオブジェクト) | |
view を constant_range に変換する(クラステンプレート) (rangeアダプタオブジェクト) | |
tuple-like な値からなるviewと数値Nを取り、各タプルのN番目の要素のviewを生成する(クラステンプレート) (rangeアダプタオブジェクト) | |
| (C++20) |
ペアのような値からなるviewを取り、各ペアの最初の要素のviewを生成する(クラステンプレート) (rangeアダプタオブジェクト) |
ペアのような値からなるviewを取り、各ペアの2番目の要素のviewを生成する(クラステンプレート) (rangeアダプタオブジェクト) | |
適合するシーケンスの各要素を、その要素の位置と値の両方を含むタプルにマッピングする view(クラステンプレート) (rangeアダプタオブジェクト) | |
| (C++23) |
適合するviewの対応する要素への参照のタプルからなる view(クラステンプレート) (カスタマイゼーションポイントオブジェクト) |
適合するviewの対応する要素に変換関数を適用した結果からなる view(クラステンプレート) (カスタマイゼーションポイントオブジェクト) | |
適合するviewの隣接する要素への参照のタプルからなる view(クラステンプレート) (rangeアダプタオブジェクト) | |
適合するviewの隣接する要素に変換関数を適用した結果からなる view(クラステンプレート) (rangeアダプタオブジェクト) | |
別のviewの要素をN個ずつの重複しない連続したチャンクにしたviewのrange(クラステンプレート) (rangeアダプタオブジェクト) | |
M番目の要素が別のviewのM番目から(M + N - 1)番目の要素に対するviewであるview(クラステンプレート) (rangeアダプタオブジェクト) | |
与えられた述語がfalseを返す隣接要素のペアごとにviewを部分rangeに分割する(クラステンプレート) (rangeアダプタオブジェクト) | |
別のviewの要素からなり、一度にN個の要素を飛ばして進む view(クラステンプレート) (rangeアダプタオブジェクト) | |
適合するviewのn項デカルト積によって計算された結果のタプルからなる view(クラステンプレート) (カスタマイゼーションポイントオブジェクト) | |
基になるシーケンスの最後にアクセスされた要素をキャッシュする view(クラステンプレート) (rangeアダプタオブジェクト) | |
viewをinput_rangeのみで、非common_rangeであるrangeに変換する(クラステンプレート) (rangeアダプタオブジェクト) | |
[編集] Rangeジェネレータ (C++23以降)
| ヘッダ
<generator> で定義 | |
| 名前空間
std で定義 | |
| (C++23) |
同期的なコルーチンジェネレータを表す view(クラステンプレート) |
[編集] ヘルパーアイテム
[編集] Rangeアダプタオブジェクト
RangeAdaptorObject (RAO) を参照。
[編集] Rangeアダプタクロージャオブジェクト
RangeAdaptorClosureObject (RACO) を参照。
[編集] カスタマイゼーションポイントオブジェクト
カスタマイゼーションポイントオブジェクト (CPO) を参照。
[編集] 代入可能なラッパー
いくつかのrangeアダプタは、その要素や関数オブジェクトを copyable-box(C++23まで)movable-box(C++23以降) でラップします。このラッパーは、ラップされたオブジェクトに必要に応じて代入可能性を追加します。
[編集] 伝播しないキャッシュ
いくつかのrangeアダプタは、説明専用のクラステンプレート non-propagating-cache で規定されています。これは std::optional<T> とほぼ同様に振る舞います(違いについては説明を参照)。
[編集] 条件付きconst型
template< bool Const, class T > using /*maybe-const*/ = std::conditional_t<Const, const T, T>; |
(説明用*) | |
エイリアステンプレート /*maybe-const*/ は、型 T に条件付きで const 修飾子を適用するための短縮形です。
[編集] 整数のような型のヘルパーテンプレート
template< /*is-integer-like*/ T > using /*make-signed-like-t*/<T> = /* 説明を参照 */; |
(1) | (説明用*) |
template< /*is-integer-like*/ T > using /*make-unsigned-like-t*/<T> = /* 説明を参照 */; |
(2) | (説明用*) |
template< /*is-integer-like*/ T > /*make-unsigned-like-t*/<T> /*to-unsigned-like*/( T t ) |
(3) | (説明用*) |
T に対してTが整数型の場合、/*make-signed-like-t*/<T> は std::make_signed_t<T> です。- そうでない場合、/*make-signed-like-t*/<T> は
Tと同じ幅を持つ、対応する未規定の符号付き整数のような型です。
T に対してTが整数型の場合、/*make-unsigned-like-t*/<T> は std::make_unsigned_t<T> です。- そうでない場合、/*make-signed-like-t*/<T> は
Tと同じ幅を持つ、対応する未規定の符号無し整数のような型です。
[編集] カスタマイゼーションポイントオブジェクトヘルパー
template< ranges::input_range R > constexpr auto& /*possibly-const-range*/(R& r) noexcept |
(1) | (説明用*) |
template< class T > constexpr auto /*as-const-pointer*/( const T* p ) noexcept |
(2) | (説明用*) |
いくつかのrangeアクセスカスタマイゼーションポイントオブジェクトは、これらの説明専用の関数テンプレートで規定されています。
input_range をモデル化する場合、r のconst修飾版を返します。そうでない場合は、キャストせずに r を返します。[編集] Rangeアダプタヘルパー
template< class F, class Tuple > constexpr auto /*tuple-transform*/( F&& f, Tuple&& tuple ) |
(1) | (説明用*) |
template< class F, class Tuple > constexpr void /*tuple-for-each*/( F&& f, Tuple&& tuple ) |
(2) | (説明用*) |
template< class T > constexpr T& /*as-lvalue*/ { return static_cast<T&>(t); } |
(3) | (説明用*) |
いくつかのrangeアダプタは、これらの説明専用の関数テンプレートで規定されています。
[編集] ヘルパーコンセプト
以下の説明専用のコンセプトはいくつかの型で使用されますが、標準ライブラリのインターフェースの一部ではありません。
template< class R > concept /*simple-view*/ = |
(1) | (説明用*) |
template< class I > concept /*has-arrow*/ = |
(2) | (説明用*) |
template< class T, class U > concept /*different-from*/ = |
(3) | (説明用*) |
template< class R > concept /*range-with-movable-references*/ = |
(4) | (説明用*) |
template< bool C, class... Views > concept /*all-random-access*/ = |
(5) | (説明用*) |
template< bool C, class... Views > concept /*all-bidirectional*/ = |
(6) | (説明用*) |
template< bool C, class... Views > concept /*all-forward*/ = |
(7) | (説明用*) |
[編集] ノート
[編集] 例
#include <iostream> #include <ranges> int main() { auto const ints = {0, 1, 2, 3, 4, 5}; auto even = [](int i) { return 0 == i % 2; }; auto square = [](int i) { return i * i; }; // the "pipe" syntax of composing the views: for (int i : ints | std::views::filter(even) | std::views::transform(square)) std::cout << i << ' '; std::cout << '\n'; // a traditional "functional" composing syntax: for (int i : std::views::transform(std::views::filter(ints, even), square)) std::cout << i << ' '; }
出力
0 4 16 0 4 16
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 3509 (P2281R1) |
C++20 | Rangeアダプタオブジェクトが後続の引数をどのように束縛するかが不明確だった | 値によって 束縛されるようになった |
| LWG 3948 | C++23 | possibly-const-range と as-const-pointer がnoexcept として宣言されていなかった |
noexcept として宣言された |
| LWG 4027 | C++23 | possibly-const-range は、すでに constant_range をモデル化しているRangeに対してconst修飾を付加しなかった |
そのようなRangeに対して const修飾を付加するようになった |
| LWG 4112 | C++20 | has-arrow は i がconst修飾されていることを要求しなかった |
要求するようになった |