Was ist der richtige Weg, um eine Funktion zu definieren, die einen int->int
Lambda-Parameter als Referenz empfängt ?
void f(std::function< int(int) >& lambda);
oder
void f(auto& lambda);
Ich bin mir nicht sicher, ob das letzte Formular überhaupt eine legale Syntax ist.
Gibt es andere Möglichkeiten, einen Lambda-Parameter zu definieren?
const&
?Antworten:
Sie können keinen
auto
Parameter haben. Sie haben grundsätzlich zwei Möglichkeiten:Option 1: Verwenden
std::function
Sie wie gezeigt.Option 2: Verwenden Sie einen Vorlagenparameter:
template<typename F> void f(F &lambda) { /* ... */}
Option 2 kann in einigen Fällen effizienter sein, da sie eine mögliche Heap-Zuordnung für das eingebettete Lambda-Funktionsobjekt vermeiden kann, ist jedoch nur möglich, wenn
f
sie als Vorlagenfunktion in einen Header eingefügt werden kann. Dies kann auch die Kompilierungszeiten und den I-Cache-Footprint erhöhen, ebenso wie jede Vorlage. Beachten Sie, dass dies möglicherweise auch keine Auswirkung hat. Wenn das Lambda-Funktionsobjekt klein genug ist, kann es imstd::function
Objekt inline dargestellt werden.quelle
std::function
std::function
Objekt inline dargestellt werden" ist irreführend. Lambdas sind immer für Inline verfügbar (der Compiler kann dies natürlich nicht tun).std::function
Implementierungen verwenden im Allgemeinen die Optimierung kleiner Objekte, um Heap-Zuordnungen zu vermeiden. Wenn ein Lambda eine ausreichend kleine Erfassungsliste hat, wird esstd::function
ohne Verwendung des Heaps gespeichert . Ansonsten hat die Größe eines Lambdas keine wirkliche Bedeutung.&
invoid f(F & lambda)
?Ich würde verwenden
template
als: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 }
Ausgabe:
500 1000 100
Demo: http://www.ideone.com/EayVq
quelle
Ich weiß, es sind 7 Jahre vergangen, 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 :: Funktion
quelle
std::function
Fall), während die Vorlagenversion diese Einschränkung nicht aufweist.Das ist knapp. Was tatsächlich kompiliert wird, ist:
#include <cassert> /*constexpr optional*/ const auto f = [](auto &&lambda) { lambda(); lambda(); }; int main() { int counter = 0; f([&]{ ++counter; }); assert(counter == 2); }
quelle