Ich fange an, Anwendungen zu entwickeln, die C ++ 11 Lambdas verwenden, und einige Typen in Funktionszeiger konvertieren müssen. Dies funktioniert perfekt in GCC 4.6.0:
%Vor%Mein Problem ist, wenn ich lokale Funktions- oder Methodenvariablen innerhalb des Lambda verwenden muss:
%Vor%G ++ 4.6.0 gibt den Cast-Fehlercode:
%Vor%Wenn auto verwendet wird, funktioniert es:
%Vor%Meine Frage ist: Wie kann ich mit [& amp; amp; <] einen Typ für ein Lambda erstellen? In meinem Fall kann ich die STL std :: function nicht verwenden (weil mein Programm C ++ RTTI und EXCEPTIONS runtime nicht verwendet), und es hat eine einfache Implementierung von Funktion, um dieses Problem zu lösen?
Ich kann nicht die STL std :: -Funktion verwenden (weil mein Programm nicht C ++ RTTI und EXCEPTIONS Laufzeit verwendet)
Dann müssen Sie möglicherweise Ihr eigenes Äquivalent zu std::function
schreiben.
Die übliche Implementierung des Typs löscht für std::function
benötigt für die meisten Funktionen keine RTTI; Es funktioniert durch regelmäßige virtuelle Funktionsaufrufe. So schreiben Sie Ihre eigene Version ist machbar.
Tatsächlich sind die einzigen Dinge in std::function
, die RTTI benötigen, die Funktionen target_type
und target
, die nicht die nützlichsten Funktionen der Welt sind. Sie können möglicherweise std::function
verwenden, ohne diese Funktionen aufzurufen, vorausgesetzt, die von Ihnen verwendete Implementierung benötigt RTTI nicht für ihre üblichen Aufgaben.
Wenn Sie die Ausnahmebehandlung deaktivieren, wird das Programm normalerweise beendet und es treten Fehler auf, wenn Sie auf eine throw
-Anweisung stoßen. Und da die meisten der Ausnahmen, die ein std::function
ausgeben würde, nicht die Art von Sache sind, von der Sie wiederherstellen könnten (Aufruf eines leeren function
, nicht genügend Arbeitsspeicher usw.), können Sie wahrscheinlich einfach% co_de verwenden % wie es ist.
Nur Lambdas ohne Capture können in einen Funktionszeiger konvertiert werden. Dies ist eine Erweiterung von Lambdas nur für diesen speziellen Fall [*]. Im Allgemeinen sind Lambdas Funktionsobjekte, und Sie können ein Funktionsobjekt nicht in eine Funktion konvertieren.
Die Alternative für lambdas, die den Status (Capture) haben, besteht darin, std::function
anstelle eines einfachen Funktionszeigers zu verwenden.
[*]: Wenn das Lambda, das den Zustand hält, in den Funktionszeiger umgewandelt werden könnte, wo würde der Zustand beibehalten? (Beachten Sie, dass es mehrere Instanzen dieses bestimmten Lambda geben kann, von denen jeder seinen eigenen Status hat, der getrennt verwaltet werden muss)
Wie bereits erwähnt, können nur Lambdas, die nichts erfassen, in Funktionszeiger umgewandelt werden.
Wenn Sie nicht etwas wie std :: function verwenden oder schreiben wollen, besteht eine andere Alternative darin, als Parameter die Dinge zu übergeben, die Sie sonst erfassen würden. Sie können sogar eine Struktur erstellen, um sie zu halten.
%Vor%Eine andere Alternative ist die Verwendung von globalen / statischen / thread_local / constexpr Variablen, die keine Erfassung erfordern.
Sie können std::function
verwenden, es benötigt keine "Laufzeit". Andernfalls sehen Sie hier nach, wie Sie std::function
selbst implementieren .