Lambda-Ausdrücke als CLR (.NET) die Delegierten / event-Handler in Visual C++ 2010
Ist es möglich, mit der neuen lambda-Ausdrücke in Visual C++ 2010 als CLR-Ereignis-Handler? Ich habe versucht den folgenden code:
SomeEvent += gcnew EventHandler(
[] (Object^ sender, EventArgs^ e) {
//code here
}
);
Es Ergebnisse in der folgenden Fehlermeldung:
Fehler C3364: "System::EventHandler' : ungültiges argument für den Konstruktor delegieren; Delegierter Ziel muss ein Zeiger auf eine member-Funktion
Bin ich versucht das Unmögliche, oder ist einfach meine syntax falsch?
- Check meine Lösung "Lambda2Delegate" hier gepostet stackoverflow.com/a/26552573/2604941
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nicht, die C++/CLI-compiler nicht aktualisiert zu akzeptieren, die lambda-syntax. Ziemlich ironisch übrigens angesichts der head-start, die verwalteten code hatte.
[&, &this]
- wie im lambda-Ausdruck kann ändern, was auch immer ist in seinem Eltern-scope, so könnten Sie haben gerade gefordert, dass C++ lambdas muss eine solche capture-Klausel.Func<int, int, int>^ f1 = make_delegate([&](int x, int y) { return x + y; });
. Das problem dabei ist, dass, da synthetisiert lambda-Typ nicht verwaltet wird, kann es nicht enthalten, die verwalteten Typen - was bedeutet, dass eine solche lambda nicht erfassen managed object references (T^
). Sie könnengcroot<T>
statt, natürlich, aber es ist immer noch unbequem, und ich Frage mich, über perf Auswirkungen. Jedenfalls kann ich teilen den code, wenn Sie wollen.ref class
. Darüber hinaus ein lambda-Ausdruck erfasst auch die Umgebung, und Sie müssen es manuell tun, für eine member-Funktion.Folgende ist meine Lösung, die es uns ermöglicht zu wickeln lambdas (wie auch alle Funktions-Objekte - also alles, was auf die
operator()
genannt werden kann) in die Delegiertenversammlung. Es hat einige Grenzen - genauer gesagt, Sie unterstützt jedoch nicht die Delegierten mit der tracking-Referenz Parameter (%
in C++/CLI,ref
/out
in C#); und es gibt eine Obergrenze für die Anzahl der Parameter kann die Stellvertretung nehmen (weil VC++2010 bietet keine Unterstützung vararg-Vorlagen), obwohl der code trivial angepasst zu unterstützen, um so viele wie Sie möchten.Beispiel für die Nutzung:
Während dies technisch funktioniert, was Sie wollen, die praktische Anwendungen sind etwas begrenzt aufgrund der Tatsache, dass C++0x-Lambda-Ausdrücke erweitert werden, in einfachen Klassen, nicht
ref
odervalue
lieben. Da plain Klassen enthalten, nicht verwalteten Typen in C++/CLI (also keine Mitglieder von Objekt-handle-Typ, keine Mitglieder der tracking-Referenz-Typ, und die keine Mitglieder dervalue class
geben), das bedeutet, dass Lambda-Ausdrücke können nicht erfassen alle Variablen dieser Typen, entweder. Es gibt keine Problemumgehung, ich bin mir bewusst, der für die Verfolgung von Referenzen. Fürvalue class
Sie können einen nicht verwalteten Zeiger darauf (pin_ptr
falls erforderlich), und erfassen, dass.Für die Objekt-handles, Sie können speichern Sie in
gcroot<T>
festhalten, dass - aber es gibt schwerwiegende Auswirkungen auf die Leistung - in meinen tests, die Zugriff auf ein Mitglied übergcroot<T>
ist etwa 40 mal langsamer als wenn man es mit einem einfachen Objekt-handle. Es ist eigentlich nicht viel in absoluten Maßnahme für einen einzelnen Anruf, aber für etwas, das nennt sich wiederholt in einer Schleife, die sagen, die meisten LINQ-algorithmen - es wäre ein killer. Beachten Sie aber, dass dies nur gilt, wenn Sie brauchen, um zu erfassen, ein Griff in die lambda! Wenn Sie einfach verwenden, um schreiben Sie ein Prädikat, das inline oder zu aktualisieren, einen Zähler, dann funktioniert es einwandfrei.Diese Seite hat ein paar Beispiele für lambdas in C++:
http://msdn.microsoft.com/en-us/library/dd293608%28v=VS.100%29.aspx
Microsoft VS2010 C++ Verbesserungen Aussehen, wie Sie tatsächlich umsetzen C++0x-lambda-spec. Als solche sind Sie rein ungepflegt und sind der Typ
lambda
.Es ist nichts in der Microsoft-Dokumentation, die Hinweise auf die Möglichkeit der Verwendung von C++ - Lambda-Ausdrücke als CLR-lambdas. In dieser Phase muss ich sagen, dass man nicht mit C++ Lambda-Ausdrücke als Ereignishandler für verwalteten Delegierten.