tutorial sintaxis expresiones c++ function c++11 lambda

c++ - expresiones - lambda sintaxis



Función que devuelve una expresión lambda (4)

Me pregunto si es posible escribir una función que devuelva una función lambda en C ++ 11. Por supuesto, un problema es cómo declarar tal función. Cada lambda tiene un tipo, pero ese tipo no se puede expresar en C ++. No creo que esto funcione:

auto retFun() -> decltype ([](int x) -> int) { return [](int x) { return x; } }

Ni esto:

int(int) retFun();

No estoy al tanto de ninguna conversión automática de lambdas a, digamos, punteros a funciones, o algo así. ¿Es la única solución que elabora a mano un objeto de función y lo devuelve?


Aunque la pregunta específicamente hace referencia a C ++ 11, por el bien de otros que se topan con esto y tienen acceso a un compilador C ++ 14, C ++ 14 ahora permite tipos de retorno deducidos para funciones ordinarias. Por lo tanto, el ejemplo de la pregunta se puede ajustar simplemente para que funcione como se desea simplemente -> decltype cláusula -> decltype ... después de la lista de parámetros de funciones:

auto retFun() { return [](int x) { return x; } }

Sin embargo, tenga en cuenta que esto no funcionará si hay más de un return <lambda>; aparece en la función. Esto se debe a que una restricción en la deducción del tipo de retorno es que todas las declaraciones de retorno deben devolver expresiones del mismo tipo, pero cada objeto lambda recibe su propio tipo único por parte del compilador, por lo que el return <lambda>; las expresiones tendrán cada uno un tipo diferente.


No necesita un objeto de función hecho a mano, solo use std::function , cuyas funciones lambda son convertibles:

std::function<int (int)> retFun() { return [](int x) { return x; }; }


Para este simple ejemplo, no necesita std::function .

Del estándar §5.1.2 / 6:

El tipo de cierre para una expresión lambda sin captura lambda tiene una función pública no virtual de conversión constante no virtual para señalar a la función que tiene el mismo parámetro y tipos de retorno que el operador de llamada de función del tipo de cierre. El valor devuelto por esta función de conversión será la dirección de una función que, cuando se invoca, tiene el mismo efecto que invocar al operador de llamada de función del tipo de cierre.

Como su función no tiene una captura, significa que la lambda se puede convertir a un puntero a la función de tipo int (*)(int) :

typedef int (*identity_t)(int); // works with gcc identity_t retFun() { return [](int x) { return x; }; }

Esa es mi opinión, corrígeme si me equivoco.


Puede devolver la función lambda desde otra función lambda, ya que no debe especificar explícitamente el tipo de retorno de la función lambda. Simplemente escriba algo así en alcance global:

auto retFun = []() { return [](int x) {return x;}; };