Option 2 kann in einigen Fällen effizienter sein, da sie eine potenzielle Heap-Zuweisung für das eingebettete Lambda-Funktionsobjekt vermeiden kann, aber nur dann möglich ist f kann als Template-Funktion in einem Header platziert werden. Es kann auch die Kompilierungszeiten und den I-Cache-Fußabdruck erhöhen, wie dies bei jedem Template der Fall sein kann. Beachten Sie, dass dies möglicherweise auch keine Auswirkungen hat, da das Lambda-Funktionsobjekt, wenn es klein genug ist, inline in dargestellt werden kann std::function Objekt.
Vorlagen können auch den I-Cache-Fußabdruck verbessern, indem Sprünge zu allgemeinem nicht lokalem Code eliminiert werden (in diesem Fall führen Sie Ihr Lambda direkt aus, ohne durch den allgemeinen Zweck springen zu müssen std::function Verpackung zuerst)
– jalf
23. Juni 2011 um 18:17 Uhr
Dieses Zitat, “Wenn das Lambda-Funktionsobjekt klein genug ist, kann es inline in der dargestellt werden std::function Objekt” ist irreführend. Lambdas sind immer für Inline verfügbar (der Compiler kann sich natürlich dagegen entscheiden). std::function Implementierungen verwenden im Allgemeinen die Optimierung kleiner Objekte, um Heap-Zuweisungen zu vermeiden. Wenn ein Lambda klein genug ist Capture-Liste es wird darin gespeichert std::function ohne den Haufen zu benutzen. Abgesehen davon hat die Größe eines Lambdas keine wirkliche Bedeutung.
– geschickt_code
23. Juni 2011 um 18:20 Uhr
@bdonlan: Übrigens, warum ist da & in void f(F & lambda)?
– Nawaz
23. Juni 2011 um 18:20 Uhr
@bdonlan: Aber die Konstante & geht davon aus, dass die Mitglieder des Lambda (die Capture-by-Values) nicht geändert werden können. Was möglicherweise nicht das ist, was der Benutzer möchte.
– Nicol Bolas
24. Juni 2011 um 1:57 Uhr
@bdonlan Es ist eine Weile her, aber das Übergeben als nicht konstante Referenz erlaubt keine Konstruktion eines temporären Lambda im Funktionsaufruf. Hier wäre eine R-Wert-Referenz am besten.
– zennehoy
11. September 2013 um 8:42 Uhr
Nawaz
ich würde … benutzen template wie:
template<typename Functor>
void f(Functor functor)
{
cout << functor(10) << endl;
}
int g(int x)
{
return x * x;
}
int main()
{
auto lambda = [] (int x) { cout << x * 50 << endl; return x * 100; };
f(lambda); //pass lambda
f(g); //pass function
}
Ich weiß, es ist 7 Jahre her, aber hier ist ein Weg, den sonst niemand erwähnt hat:
void foo(void (*f)(int)){
std::cout<<"foo"<<std::endl;
f(1); // calls lambda which takes an int and returns void
}
int main(){
foo([](int a){std::cout<<"lambda "<<a<<std::endl;});
}
Welche Ausgänge:
foo
lambda 1
Keine Notwendigkeit für Vorlagen oder std::function
Dies ist nur auf Lambdas beschränkt, die in Funktionszeiger zerfallen können (Lambdas ohne Captures), und erfordert auch die Angabe einer genauen Signatur (wie bei for std::function Fall), während die Vorlagenversion diese Einschränkung nicht hat.
Wenn Platzhaltertypen (entweder auto oder Concept auto) in der Parameterliste einer Funktionsdeklaration oder einer Funktionsvorlagendeklaration erscheinen, die Deklaration eine Funktionsvorlage deklariert und ein erfundener Vorlagenparameter für jeden Platzhalter an die Vorlagenparameterliste angehängt wird
und es entspricht genau Option 2 in @bdonlans Antwort:
Warum brauchen Sie das Lambda als Referenz? Meinst du
const&
?– geschickt_code
23. Juni 2011 um 18:13 Uhr