C ++ 11 Lambdas zum Funktionszeiger

8

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?

    
Raphael Basso 12.06.2012, 13:01
quelle

4 Antworten

8
  

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.

    
Nicol Bolas 12.06.2012, 14:14
quelle
8

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)

    
quelle
6

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.

    
bames53 12.06.2012 18:06
quelle
2

Sie können std::function verwenden, es benötigt keine "Laufzeit". Andernfalls sehen Sie hier nach, wie Sie std::function selbst implementieren .

    
jpalecek 12.06.2012 13:10
quelle

Tags und Links