Was diskutiert wird, ist im Wesentlichen der Unterschied zwischen einer Push-basierten Verarbeitungsmethode und einer Pull-basierten Verarbeitungsmethode. In einem Push-System wie dieser Pipes-Bibliothek erstellen Sie eine Verarbeitungskette, und jeder Verarbeitungsschritt überträgt seine Daten direkt in den nächsten. In einem Pull-System-ähnlichen Bereich erstellen Sie eine Darstellung von Daten, auf die Sie zugreifen und die Sie nach Bedarf ändern können. Die Verarbeitung erfolgt nicht von alleine. Dies geschieht nur, wenn jemand versucht, die Reichweite zu nutzen.
Die Operationen unzip
und fork
sind beide Eins-zu-Viele-Operationen: Sie nehmen eine einzelne Eingabe und ordnen sie vielen Verarbeitungsoperationen zu.
Als Push-System kann die Pipes-Bibliothek aufgrund der Struktur ihrer API Eins-zu-Viele-Operationen ausführen. Eine Operation wird durch einen Funktionsaufruf dargestellt. Die Eingabe wird durch den Verwendungsort impliziert (Verwendung >>=
oder Weitergabe an einen Prozessor). Die Parameter der Funktion definieren ihre Ausgabe (ignorieren Parameter, die für den Prozessor selbst bestimmt sind). Und da C ++ - Funktionen eine beliebige Anzahl von Parametern haben können, fällt natürlich eine Eins-zu-Viele-Zuordnungsoperation aus. Sie liefern einfach geeignete Prozessoren für die verschiedenen Ausgänge.
Als Pull-System basieren Bereiche auf Rückgabewerten. C ++ hat keinen Sprachmechanismus für die Rückgabe mehrerer Werte. Das Beste, was wir tun können, ist, einen "Wert" zurückzugeben, der mehrere Werte darstellt.
Die Verkettung von Bereichsadaptern basiert jedoch letztendlich darauf, dass die Eingaben Bereiche sind . Und ein "Wert", der mehrere Werte darstellt, ist selbst kein Bereich. Es kann Bereiche enthalten, aber das macht es nicht zu einem Bereich.
Jetzt müssen Sie diesen definitiv "kein Bereich" -Typ verwenden und alle Ihre Bereichsadapter damit arbeiten lassen. Durch Anwenden eines Bereichsadapters muss dieser Vorgang typübergreifend übertragen werden, wodurch ein Viele-zu-Viele-Vorgang erstellt wird. Das zu tun ist nicht einfach.
Aber was noch wichtiger ist ... das ist wahrscheinlich nicht das, was Sie wollen . Wenn Sie fork
einen Bereich haben, möchten Sie mit ziemlicher Sicherheit eine andere Verarbeitung für die replizierten Bereiche durchführen. Und das schließt jede Möglichkeit, die |
Operation dazu zu verwenden, vollständig aus . Sie müssen Möglichkeiten entwickeln, um Adapter auf bestimmte Teile dieser Bereichstupel anzuwenden. Und diese Wege werden zunehmend wie ein Push-basierter Prozessor aussehen.
Letztendlich hat ein Pull-Style-System nur einen Ausgang auf jeder Ebene. Dies ist nur ein Teil des Kernkonzepts einer solchen API: Jeder Verarbeitungsschritt generiert einen Bereich. Dies hat seine Vorteile (verzögerte Verarbeitung), aber die Darstellung von Eins-zu-Viele-Operationen ist eine seiner Schwachstellen.
Bereiche können sicherlich eine unzip
Funktion haben ( fork
kopiert wirklich nur den Bereich). Aber es wäre kein |
Stiladapter; Es wäre eine Funktion, die einen Bereich über einen zerlegbaren Typ nimmt und ein Tupel von Bereichen zurückgibt. Wenn Sie mehr mit ihnen verarbeiten möchten, müssen Sie das Tupel in einem Wert speichern, auf die einzelnen Elemente zugreifen und sie nach Belieben verwenden.