Jaki jest właściwy sposób definiowania funkcji, która otrzymuje int->int
parametr lambda przez odniesienie?
void f(std::function< int(int) >& lambda);
lub
void f(auto& lambda);
Nie jestem pewien, czy ostatnia forma jest nawet legalną składnią.
Czy istnieją inne sposoby definiowania parametru lambda?
const&
?Odpowiedzi:
Nie możesz mieć
auto
parametru. Zasadniczo masz dwie opcje:Opcja nr 1: Użyj,
std::function
jak pokazano.Opcja nr 2: użyj parametru szablonu:
template<typename F> void f(F &lambda) { /* ... */}
Opcja nr 2 może w niektórych przypadkach być bardziej wydajna, ponieważ pozwala uniknąć potencjalnej alokacji sterty dla osadzonego obiektu funkcji lambda, ale jest możliwa tylko wtedy, gdy
f
można ją umieścić w nagłówku jako funkcję szablonu. Może również wydłużyć czas kompilacji i zwiększyć rozmiar pamięci podręcznej I-cache, podobnie jak każdy szablon. Zauważ, że może to również nie mieć żadnego efektu, ponieważ jeśli obiekt funkcji lambda jest wystarczająco mały, może być reprezentowany wstd::function
obiekcie.źródło
std::function
opakowanie ogólnego przeznaczenia )std::function
obiekcie” jest mylący. Lambdy są zawsze dostępne dla inline (kompilator może oczywiście nie zdecydować się na to).std::function
implementacje zazwyczaj używają optymalizacji małych obiektów, aby uniknąć alokacji sterty. Jeśli lambda ma wystarczająco małą listę przechwytywania , zostanie zapisanastd::function
bez użycia sterty. Poza tym rozmiar lambdy nie ma żadnego znaczenia.&
wvoid f(F & lambda)
?Użyłbym
template
jako: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 }
Wynik:
500 1000 100
Demo: http://www.ideone.com/EayVq
źródło
Wiem, że minęło 7 lat, ale oto sposób, o którym nikt inny nie wspomniał:
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;}); }
Które wyjścia:
foo lambda 1
Nie potrzeba szablonów ani funkcji std ::
źródło
std::function
przypadku przypadku), podczas gdy wersja szablonowa nie ma tego ograniczenia.To blisko. Właściwie skompiluje się:
#include <cassert> /*constexpr optional*/ const auto f = [](auto &&lambda) { lambda(); lambda(); }; int main() { int counter = 0; f([&]{ ++counter; }); assert(counter == 2); }
źródło