Lazy Transformation in C ++

8

Ich habe das folgende Python-Snippet, das ich mit C ++ reproduzieren möchte:

%Vor%

Ich habe von Boost Phoenix gehört, aber Ich konnte kein Beispiel für ein faules transform finden, das sich genauso verhält wie Pythons imap .

Edit: Um meine Frage zu klären, geht es nicht nur darum, Funktionen in der Reihenfolge mit for anzuwenden, sondern Algorithmen wie std::transform für unendliche Generatoren zu verwenden. Die Art und Weise, wie die Funktionen zusammengesetzt sind (in einer funktionaleren Sprache wie dem Dialekt), ist ebenfalls wichtig, da der nächste Schritt die Komposition der Funktionen ist.

Update: Danke Bradgronesurfing, David Brown und Xeo für die tollen Antworten! Ich habe mich für Xeo entschieden, weil es das prägnanteste ist, und es bringt mich dahin, wo ich sein wollte, aber Davids war sehr wichtig, um die Konzepte durchzubringen. Auch, bradgonesurfing's Tipp Boost :: Range:).

    
bruno nery 30.10.2012, 17:14
quelle

5 Antworten

11
4

Ich denke, der am meisten idiomatische Weg, dies in C ++ zu tun, ist mit Iteratoren. Hier ist eine Basis-Iterator-Klasse, die einen Iterator verwendet und eine Funktion auf ihr Ergebnis anwendet:

%Vor%

Dies ist nur ein einfaches Beispiel und ist immer noch unvollständig, da es keine Möglichkeit gibt zu überprüfen, ob Sie das Ende der iterierbaren Sequenz erreicht haben.

Hier ist eine Wiederholung Ihres Beispiel-Python-Codes (der auch eine einfache unendliche Zählerklasse definiert).

%Vor%

Abgesehen von den Klassendefinitionen (die nur reproduzieren, was die Python-Bibliothek tut), ist der Code ungefähr so ​​lang wie die Python-Version.

    
David Brown 30.10.2012 17:54
quelle
2

Ich denke, dass die boost :: rangex-Bibliothek genau das ist, wonach Sie suchen. Es sollte gut mit der neuen C ++ Lambda-Syntax funktionieren.

    
bradgonesurfing 30.10.2012 17:28
quelle
2
%Vor%

Ich weiß, es ist nicht ganz das, was Sie erwartet haben, aber es wird sicherlich zu dem Zeitpunkt ausgewertet, zu dem Sie es wollen, allerdings nicht mit einem Iterator-Iterface. Ein sehr verwandter Artikel ist dies:

Komponentenprogrammierung in D

Bearbeiten 6 / Nov / 12:

Eine Alternative, die immer noch an C ++ klebt, ist die Verwendung von Funktionszeigern und das Konstruieren eigener Pipes für die obigen Funktionen (Vektor von Funktionszeigern von SO q: Wie kann ich den Funktionszeiger im Vektor speichern? ):

%Vor%

Dies soll alle Funktionen in einem Vektor von solchen durchlaufen und den resultierenden Wert zurückgeben. Dann können Sie:

%Vor%

Natürlich könnten Sie auch einen Wrapper dafür über eine Struktur erstellen (ich würde eine Schließung verwenden, wenn C ++ sie gemacht hätte ...):

%Vor%

Oder so ähnlich. Vorbehalt: Keine Ahnung, was dies tun wird, wenn die Zeiger zwischen Threads übergeben werden.

Zusätzlicher Vorbehalt: Wenn Sie dies mit variierenden Funktionsschnittstellen tun wollen, werden Sie am Ende eine Ladung von void *(void *)(void *) -Funktionen haben müssen, damit sie alles aufnehmen und ausstrahlen können, oder eine Menge Templating, um die Art von zu beheben Rohr hast du. Ich nehme an, Sie würden im Idealfall verschiedene Arten von Pipes für verschiedene Schnittstellen zwischen Funktionen erstellen, so dass a | b | c auch dann funktioniert, wenn sie verschiedene Typen zwischen ihnen übergeben. Aber ich gehe davon aus, dass das Boost-Zeug hauptsächlich damit arbeitet.

    
Phil H 30.10.2012 17:19
quelle
-3

Abhängig von der Einfachheit der Funktionen:

%Vor%     
lucasg 30.10.2012 17:29
quelle