2014-10-24 15 views
6

Ich habe viele C# -Erfahrung vorher, aber ich bin neu in C++. Ich habe dieses Problem beim Versuch gesehen, Lambda zu verwenden, wie ich es früher getan habe.Kann ich eine C++ - Lambda-Funktion ohne Auto definieren?

Zum Beispiel:

auto compare = [] (int i1, int i2) { return i1*2 > i2; } 

Gibt es eine Möglichkeit, das Lambda mit einer bestimmten Art zu definieren, anstatt Auto Abzug?

Ich frage das, weil ich ein gemeinsames Lambda für meine Klasse definieren möchte. Dieses Lambada wird an mehreren Orten verwendet, so dass ich sie nicht mehrfach definieren möchte. 'Auto' kann jedoch nur für statische Member verwendet werden, während ich andererseits auf nicht statische Felder im Lambda zugreifen möchte.

+1

Versuchen Sie es mit [std :: function] (http://www.cplusplus.com/reference/functional/function/function/). – Nard

+0

Sie können auf nicht statische Felder zugreifen, indem Sie 'this' erfassen. – cdhowie

Antwort

7

Sie verwenden std :: function. std :: function kann einen beliebigen Lambda oder Function Zeiger glob. http://en.cppreference.com/w/cpp/utility/functional/function

std::function< bool(int, int) > myFunc = [](int x, int y){ return x > y; };

+2

Beachten Sie, dass 'std :: function' wegen der Dynamik weniger effizient ist. Normalerweise ist das egal. –

+0

@siyu weniger effizient als Lambdas, aber effizienter als so ziemlich jede andere Sprache äquivalente Abstraktion. 1.5-3x der Aufruf-Overhead eines Funktionszeigers, den ich zuletzt überprüft habe (vtable lookup, dann call). Es gibt "std :: function" Implementierungen, die rivsl Funktionszeiger, aber nicht in den wichtigsten Bibliotheken, die ich kenne. – Yakk

+0

Wenn Sie sich über den Leistungseinbruch der std :: -Funktion fürchten, dann gibt es wahrscheinlich bessere Fragen zu stellen, warum Sie Lambdas in einer leistungsabhängigen Umgebung verwenden. – BlamKiwi

3

Sie std::function verwenden könnte, aber wenn das nicht effizient genug sein würde, könnten Sie ein Funktor Objekt schreiben, was lambdas hinter den Kulissen tun ähnelt:

auto compare = [] (int i1, int i2) { return i1*2 > i2; } 

fast die das gleiche wie

struct Functor { 
    bool operator()(int i1, int i2) const { return i1*2 > i2; } 
}; 
Functor compare; 

Wenn der Funktor eine Variable im Kontext erfassen soll (zB das "Dies" -Poi) nter), müssen Sie Mitglieder innerhalb der Funktor und initialisieren sie im Konstruktor hinzu:

auto foo = [this] (int i) { return this->bar(i); } 

ist fast die gleiche wie

struct Functor { 
    Object *that; 
    Functor(Object *that) : that(that) {} 
    void operator()(int i) const { return that->bar(i); } 
}; 
Functor foo(this); 
0

Sie als std::function<Signature> verwenden können, wie erwähnt, aber auf Kosten der löscht das Lambda. Dies wird eine Indirection (im Grunde ein virtueller Funktionsaufruf) hinzufügen, wenn Sie Ihr Lambda aufrufen. Denken Sie daran, es ist weniger effizient, wenn Sie es in einem Kontext verwenden, in dem dies von Bedeutung ist.

Verwandte Themen