Ich benutze regelmäßig boost.lambda (und phoenix), um Lambda-Funktionen in C ++ zu definieren. Ich mag ihre polymorphe Eigenschaft, die Einfachheit ihrer Darstellung und die Art, wie sie die funktionale Programmierung in C ++ so viel einfacher machen. In einigen Fällen ist es sogar sauberer und besser lesbar (wenn Sie daran gewöhnt sind, sie zu lesen), um kleine Funktionen zu definieren und sie im statischen Bereich zu benennen.
Am besten speichern Sie diese Funktionen, die konventionellen Funktionen ähneln, in boost::function
Aber das Problem ist die Ineffizienz der Laufzeit. Auch wenn die Funktion add
hier zustandslos ist, ist der zurückgegebene Lambda-Typ nicht leer und sein sizeof
ist größer als 1 (also boost::function
default ctor und copy ctor wird new
enthalten). Ich bezweifle wirklich, dass es einen Mechanismus von der Compiler- oder der Boost-Seite gibt, um diese Staatenlosigkeit zu erkennen und Code zu erzeugen, der der Verwendung von:
Man könnte natürlich c ++ 11 auto
verwenden, aber dann kann die Variable nicht um nicht vorlagenbasierte Kontexte weitergegeben werden. Ich habe es schließlich geschafft, fast das zu tun, was ich will, indem ich den folgenden Ansatz benutze:
Kompiliert mit gcc 4.6.1 Die Ausgabe von diesem Programm ist (unabhängig von der Optimierungsstufe):
%Vor% wie erwartet. Hier behalte ich einen statischen Zeiger auf den Lambda-Ausdruckstyp (so konstant wie möglich für Optimierungszwecke) und initialisiere ihn auf NULL
. Auf diese Weise erhalten Sie einen Laufzeitfehler, wenn Sie versuchen, einen Lambda-Ausdruck mit Status zu "statifizieren". Und wenn Sie einen wirklich staatenlosen Lambda-Ausdruck sta- bilisieren, funktioniert alles.
Weiter zu den Fragen:
Die Methode scheint ein wenig dreckig zu sein, können Sie an irgendeinen Umstand oder eine Compiler-Annahme denken, die dieses Fehlverhalten verursachen wird (erwartetes Verhalten: funktioniert gut, wenn Lambda staatenlos ist, sonst segfault).
Können Sie sich vorstellen, dass dies zu einem Compiler-Fehler führt, wenn der Lambda-Ausdruck den Status "?" hat?
EDIT nach Eric Niebler's Antwort:
%Vor%Sie sagten, Sie mögen die polymorphe Natur von Boosts Lambda-Funktionen, aber Sie verwenden diese Eigenschaft nicht in Ihrem obigen Code. Mein Vorschlag: Verwenden Sie C ++ 11 Lambdas. Die Stateless haben bereits eine implizite Umwandlung in rohe Funktionszeiger. Es ist genau das, wonach Sie suchen, IMO.
=== UPDATE ===
Obwohl das Aufrufen einer Memberfunktion über einen Nullzeiger eine schreckliche Idee ist (tue es nicht, du wirst blind werden), kannst du standardmäßig ein NEU Lambda-Objekt des gleichen Typs des Originals. Wenn Sie das mit meinem Vorschlag in # 2 oben kombinieren, können Sie bekommen, wonach Sie suchen. Hier ist der Code:
%Vor%Haftungsausschluss: Ich bin nicht der Autor von Phoenix. Ich weiß nicht, ob die Standardkonstruierbarkeit für alle statuslosen Lambdas garantiert ist.
Getestet mit MSVC-10.0.
Viel Spaß!
Tags und Links c++ lambda boost boost-phoenix boost-proto