2014-10-24 21 views
6

Ho già un sacco di esperienza in C# ma sono nuovo di C++. Ho visto questo problema quando ho provato a usare lambda come facevo.Posso definire una funzione lambda C++ senza auto?

Ad esempio:

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

C'è un modo per definire il lambda con un tipo specifico, piuttosto che la deduzione automatica?

Lo chiedo perché voglio definire un lambda comune per la mia classe. Questa lambada verrà utilizzata in più posti, quindi non voglio definirli più volte. Tuttavia, 'auto' può essere usato solo su membri statici, mentre d'altra parte, voglio accedere a campi non statici nel lambda.

+1

Provare a utilizzare [std :: funzione] (http://www.cplusplus.com/reference/functional/function/function/). – Nard

+0

È possibile accedere ai campi non statici catturando 'this'. – cdhowie

risposta

7

Si utilizza std :: function. std :: function può glob qualsiasi pointer Lambda o Function. http://en.cppreference.com/w/cpp/utility/functional/function

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

+2

Si noti che 'std :: function' è meno efficiente a causa del dinamismo. Di solito non importa. –

+0

@siyu meno efficiente di lambdas, ma più efficiente dell'astrazione equivalente di qualsiasi altra lingua. 1.5-3x l'overhead di chiamata di un puntatore di funzione scorso ho controllato (ricerca vtable quindi chiamata). Ci sono le implememtazioni 'std :: function' che rivisitano i puntatori di funzione, ma non nelle principali librerie che io conosca. – Yakk

+0

Se sei così preoccupato per il successo in termini di prestazioni di std :: function allora ci sono probabilmente domande migliori da chiedersi sul perché stai usando lambdas in un ambiente sensibile alle prestazioni. – BlamKiwi

3

Si potrebbe usare std::function, ma se questo non sta per essere abbastanza efficace, si potrebbe scrivere un oggetto functor che ricorda quello lambda fanno dietro le quinte:

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

è quasi la uguale a

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

Se il funtore deve acquisire alcune variabili nel contesto (ad esempio il "questo" poi nter), è necessario aggiungere i membri all'interno del funtore e inizializzarle nel costruttore:

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

è quasi la stessa di

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

È possibile utilizzare come std::function<Signature> come detto, ma a costo di type-cancellando il lambda. Questo aggiungerà un riferimento indiretto (praticamente una chiamata di funzione virtuale) quando chiami il tuo lambda. Quindi tieni presente che è meno efficiente se lo utilizzerai in un contesto in cui ciò è importante.

Problemi correlati