2011-06-23 14 views
44

¿Cuál es la forma correcta de definir una función que recibe un parámetro lambda int->int por referencia?C++ 0x: forma correcta de recibir un lambda como parámetro por referencia

void f(std::function< int(int) >& lambda); 

o

void f(auto& lambda); 

no estoy seguro de la última forma es aún sintaxis legal.

¿Hay otras formas de definir un parámetro lambda?

+5

¿Por qué necesitaría la lambda por referencia? ¿Te refieres a 'const &'? –

Respuesta

50

No puede tener un parámetro auto. Básicamente tiene dos opciones:

Opción n. ° 1: Use std::function como lo ha demostrado.

Opción # 2: Utilice un parámetro de plantilla:

template<typename F> 
void f(F &lambda) { /* ... */} 

Opción # 2 puede, en algunos casos, ser más eficiente, ya que puede evitar un potencial de asignación de montón para el objeto función lambda integrado, pero es 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, como 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 suficientemente pequeño, puede representarse en línea en el objeto std::function.

+1

Las plantillas también pueden mejorar la huella de I-caché, eliminando los saltos al código general no local (en este caso, ejecute su lambda directamente, sin tener que pasar por la envoltura 'std :: function' de propósito general) – jalf

+5

Esta cita , _ "si el objeto de la función lambda es suficientemente pequeño, puede representarse en línea en el objeto' std :: function' _ es engañoso. Lambdas siempre están disponibles para inline (el compilador puede elegir no hacerlo, por supuesto). Las implementaciones 'std :: function' generalmente usan optimización de objetos pequeños para evitar asignaciones de pila. Si un lambda tiene una _captura list_ lo suficientemente pequeña, se almacenará en 'std :: function' sin usar el montón. Aparte de eso, el tamaño de una lambda no tiene un significado real. –

+1

@bdonlan: Por cierto, ¿por qué hay '&' en 'void f (F & lambda)'? – Nawaz

23

me gustaría utilizar 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

0

Sé que esta pregunta ya ha sido contestada, pero cuando yo estaba buscando la respuesta a esta pregunta, estaba buscando algo un poco diferente a las respuestas aquí, y creo que esto podría haber sido a lo que el OP estaba aludiendo, así que aquí está la esperanza esto ayudará a alguien más.

Digamos que tiene una función:

void print(int n) 
{ 
    printf("%i ", n); 
} 

el fin de pasar un lambda a esta función, haga lo siguiente:

print([]{ 
    return 3; 
}()); 

Esto pasará a la función 3, obviamente. Un ejemplo más útil, específicamente relacionada con la pregunta del OP, es un lambda que toma un número entero como un parámetro y devuelve un int a la función final:

int x = 3; 

auto lambdaFunction = [](int input) { 
    return (input + 1); 
}; 

print(lambdaFunction(x)); 

Esto es suponiendo que no pasa por valor o por referencia a la lambda, que puede hacer directamente:

// Pass by value 
print([=]{ 
    return (x + 1); 
}()); 

// Pass by reference 
print([&]{ 
    return (x + 1); 
}()); 
+4

Lo que estás haciendo no es "pasar una lambda a esta función", sino invocar la lambda y pasarle el valor de retorno a la función. Muy diferente de lo que OP pidió. Puede o no haber sido lo que el OP tenía originalmente en mente, pero su pregunta era claramente cómo aceptar un functor lambda como argumento de función. – Kiruse

+0

Ah, está bien. Me encontré con la pregunta de OP mientras buscaba lo que finalmente publiqué, mi error –

Cuestiones relacionadas