議論されているのは、本質的にはプッシュベースの処理方法とプルベースの方法の違いです。このパイプライブラリのようなプッシュシステムでは、一連の処理を確立し、各処理ステップでデータを次のステップに直接プッシュします。範囲のようなプルシステムでは、データの表現を確立し、必要に応じてアクセスおよび変更できます。処理はそれ自体では発生しません。誰かが範囲を消費しようとしたときにのみ発生します。
unzip
およびfork
操作は、両方の1対多の操作です:彼らは、単一の入力を取り、多くの処理操作にマップします。
プッシュシステムとして、APIの構造により、パイプライブラリは1対多の操作を処理できます。操作は関数呼び出しで表されます。入力は、使用ポイント(使用>>=
またはプロセッサへの受け渡し)によって暗示されます。関数のパラメーターは、その出力を定義します(プロセッサー自体のパラメーターは無視します)。また、C ++関数は任意の数のパラメーターを持つことができるため、1対多のマッピング操作は自然に失敗します。さまざまな出力に適切なプロセッサを供給するだけです。
プルシステムとして、範囲は戻り値に基づいています。C ++には、複数の値を返すための言語メカニズムがないため、複数の値を表す「値」を返すことが最善の方法です。
ただし、範囲アダプターの連鎖は、最終的には範囲である入力に基づいています。また、「複数の値を表す「値」」自体は範囲ではありません。範囲を含めることはできますが、範囲にはなりません。
だから今、あなたはこれを非常に間違いなく「範囲ではない」タイプにして、すべての範囲アダプタをそれで動作させる必要があります。範囲アダプターを適用すると、その操作が型全体にブロードキャストされ、多対多の操作が作成されます。それを行うのは簡単ではありません。
しかし、もっと重要なことに...それはおそらくあなたが望むものではありません。fork
範囲の場合、ほぼ確実に、複製された範囲に対して異なる処理を実行する必要があります。そして、それは|
操作を使用してそれを行う可能性を完全にシャットダウンします。これらの範囲タプルの特定の部分にアダプターを適用する方法を構築する必要があります。そして、これらの方法はますますプッシュベースのプロセッサのように見えるでしょう。
結局のところ、プルスタイルのシステムでは、各レベルに1つの出力しかありません。これは、このようなAPIのコアコンセプトの一部にすぎません。各処理ステップで範囲が生成されます。これには利点(遅延処理)がありますが、1対多の操作を表すことは、その弱点の1つです。
範囲は確かにunzip
機能を持つことができます(fork
本当に範囲をコピーするだけです)。しかし、それは|
スタイルアダプタではありません。これは、分解可能な型の範囲を取り、範囲のタプルを返す関数です。それらを使用してさらに処理を行う場合は、タプルを値に格納し、個々の要素にアクセスして、必要に応じてそれらを使用する必要があります。