C++20標準ライブラリ提供レンジアダプタstd::views::split
とstd::views::lazy_split
の比較。*1
まとめ:
- 入力レンジを区切りパターン(単一要素またはレンジ)を用いて分割し、「部分レンジ(subrange)のレンジ」へと変換するレンジアダプタ(range adaptor)。*2
- 大半のユースケースで
split
を用いればよい。- 使い勝手を重視:部分レンジ(
std::ranges::subrange
)への分割処理を遅延評価する。*3 - 入力レンジの特性が出力レンジへと引き継がれる。(例:文字列の分割結果を文字列として扱える)
- 使い勝手を重視:部分レンジ(
- 特殊ケースに対してのみ
lazy_split
を検討する。- 一般性を重視:最大限に怠惰(lazy)な分割アルゴリズムを用い、遅延生成される部分レンジを遅延生成する。
- 入力がinput_rangeの場合や、出力レンジを Const-iterable としたい場合など。
入力レンジとパターンの制約
分割対象V
と区切りパターンPattern
に対するテンプレートパラメータ制約は次の通り。
split
:V
はforward_rangeを満たすview。lazy_split
:V
はforward_rangeを満たすview、またはV
はinput_rangeを満たすviewかつPattern
が確定サイズ1要素以下のレンジ。*4- 共通:
Pattern
はforward_rangeを満たすview。
入出力レンジコンセプト
レンジアダプタの適用対象V
が満たすコンセプトに対して、適用結果の外部(Outer)レンジ/内部(Inner)レンジが満たすコンセプトは下表の通り。*5
入力\出力 | split Outer |
split Inner |
lazy_split Outer |
lazy_split Inner |
---|---|---|---|---|
input *6 | (N/A) | (N/A) | input | input |
forward | forward | forward | forward | forward |
bidirectional | forward | bidirectional | forward | forward |
random_access | forward | random_access | forward | forward |
contiguous | forward | contiguous | forward | forward |
Const-iterable性
レンジアダプタ適用後レンジの const-iterable 性(→id:yohhoy:20210701)は次の通り。
split
: 適用結果は const-iterable ではない。lazy_split
: 対象V
がforward_rangeを満たすならば、適用結果は const-iterable となる。input_rangeの場合は 非const-iterable。
関連URL
*1:ISO C++20発行後に P2210R2 が Defect Report として遡及適用されている。
*2:C++標準レンジアダプタはいずれも遅延評価を行う。実際にレンジ要素へのアクセスが必要になるまで、レンジアダプタによる各種アルゴリズムは実行されない。
*3:https://wandbox.org/permlink/1ebAmAsmrqLrLFQ8
*4:split, lazy_split ともに、確定サイズ0要素の区切りパターン(例:std:::ranges::empty<T>)によるレンジ分割にも対応する。結果として、内部(Inner)レンジ==対象レンジ要素を1個づつ取り出した単一要素レンジが得られる。
*5:表中の input は std::ranges::input_range コンセプトの略記。他 forward, bidirectional, random_access, contiguous も同様。
*6:区切りパターンに任意の forward レンジを指定できず、確定サイズが1要素以下のレンジ指定が必要となる。