2013-04-22 3 views
7

Ich habe eine Funktion getTotal:Capturing bricht mir das Lambda-Funktion

int getTotal(const HitMap& hitMap, bool(*accept)(int chan)) 

, wo das zweite Argument ist ein Bool Funktion angibt, welche Mitglieder des Behälters hitMap sollte der insgesamt hinzugefügt werden.

Ich versuche, es mit einem Lambda zu nennen. Dies funktioniert:

auto boxresult = 
getTotal(piHits, [](int pmt)->bool 
{ return (pmt/100) == 1;}); 

aber nicht:

int sector = 100; 
auto boxresult = 
getTotal(piHits, [sector](int pmt)->bool 
{ return (pmt/sector) == 1;}); 

ich den Fehler

cannot convert ‘main(int, char**)::<lambda(int)>’ to ‘bool (*)(int)’ 
for argument ‘2’ to ‘int getTotal(const HitMap&, bool (*)(int))’ 

von meinem Compiler (GCC 4.6.3). Ich versuchte [&sector] und [=sector], aber es machte keinen Unterschied.

Was mache ich falsch?

+5

Nur nicht erfassbare Lambdas können in eine Funktion * pointer * konvertiert werden. Zeitraum. – Xeo

Antwort

15

Wenn ein Lambda eine Capture-Klausel hat, kann es nicht mehr als Funktionszeiger behandelt werden. Zur Korrektur verwenden std::function<bool(int)> als Argument Typ für getTotal():

int getTotal(const HitMap& hitMap, std::function<bool(int)> accept) 
+4

Oder ... eine Vorlage. – Xeo

+1

Danke 'Vorlage int getTotal (const HitMap & hitMap, F akzeptieren)' funktioniert. Haben Sie einen Link, wo ich lesen kann, warum es mit Funktionszeigern anders ist? –

+0

Oh, [dies] (http://stackoverflow.com/a/7852154/1527126) macht Sinn. –

3

Die Lambda-Funktion mit Capturing ist nicht das, was Sie erwarten, können Sie diese Möglichkeiten nutzen:

template <typename F> 
int getTotal(const HitMap& hitMap, F accept) 
{ 

} 

oder

int getTotal(const HitMap& hitMap, std::function<bool(int)> accept) 
{ 

} 

Die Vorlage basierend getTotal hat eine bessere Leistung. Read more.