¿Cuál es la forma correcta de definir una función que recibe un int->int
parámetro lambda por referencia?
void f(std::function< int(int) >& lambda);
o
void f(auto& lambda);
No estoy seguro de que la última forma sea incluso sintaxis legal.
¿Hay otras formas de definir un parámetro lambda?
const&
?Respuestas:
No puede tener un
auto
parámetro. Básicamente tienes dos opciones:Opción # 1: Úselo
std::function
como lo ha mostrado.Opción # 2: Use un parámetro de plantilla:
template<typename F> void f(F &lambda) { /* ... */}
La opción n. ° 2 puede, en algunos casos, ser más eficiente, ya que puede evitar una posible asignación de montón para el objeto de función lambda incrustado, pero solo es posible si
f
se puede colocar en un encabezado como una función de plantilla. También puede aumentar los tiempos de compilación y la huella de I-cache, al igual que cualquier plantilla. Tenga en cuenta que también puede no tener ningún efecto, ya que si el objeto de la función lambda es lo suficientemente pequeño, puede representarse en línea en elstd::function
objeto.fuente
std::function
primero a través del contenedor de propósito general )std::function
objeto" es engañosa. Las lambdas siempre están disponibles en línea (el compilador puede optar por no hacerlo, por supuesto).std::function
Las implementaciones generalmente usan optimización de objetos pequeños para evitar asignaciones de montón. Si una lambda tiene una lista de captura lo suficientemente pequeña , se almacenarástd::function
sin usar el montón. Aparte de eso, el tamaño de una lambda no tiene ningún significado real.&
dentrovoid f(F & lambda)
?Yo usaría
template
como: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 }
Salida:
500 1000 100
Demostración: http://www.ideone.com/EayVq
fuente
Sé que han pasado 7 años, pero aquí hay una forma en que nadie más mencionó:
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;}); }
Qué salidas:
foo lambda 1
No se necesitan plantillas o std :: function
fuente
std::function
caso) mientras que la versión con plantilla no tiene esta limitación.Eso está cerca. Lo que realmente compilará es:
#include <cassert> /*constexpr optional*/ const auto f = [](auto &&lambda) { lambda(); lambda(); }; int main() { int counter = 0; f([&]{ ++counter; }); assert(counter == 2); }
fuente