En C ++ 11, ¿hay alguna forma de modelar una función lambda? ¿O es inherentemente demasiado específico para ser tentado?
Entiendo que en su lugar puedo definir una clase / functor clásico con plantilla, pero la pregunta es más como: ¿permite el lenguaje crear plantillas de funciones lambda?
Respuestas:
ACTUALIZACIÓN 2018: C ++ 20 vendrá con lambdas con plantillas y conceptualizadas. La característica ya se ha integrado en el borrador estándar.
ACTUALIZACIÓN 2014: C ++ 14 se lanzó este año y ahora proporciona lambdas polimórficas con la misma sintaxis que en este ejemplo. Algunos compiladores importantes ya lo implementan.
En su posición (en C ++ 11), lamentablemente no. Las lambdas polimórficas serían excelentes en términos de flexibilidad y potencia.
La razón original por la que terminaron siendo monomórficos fue por conceptos. Los conceptos dificultaban esta situación de código:
En una plantilla restringida solo puede llamar a otras plantillas restringidas. (De lo contrario, las restricciones no podrían verificarse). ¿Se puede
foo
invocarbar(x)
? ¿Qué restricciones tiene la lambda (el parámetro para ello es solo una plantilla, después de todo)?Los conceptos no estaban listos para abordar este tipo de cosas; requeriría más cosas como
late_check
(donde el concepto no se verificó hasta que se invocó) y otras cosas. Más simple era simplemente dejarlo todo y apegarse a las lambdas monomórficas.Sin embargo, con la eliminación de conceptos de C ++ 0x, las lambdas polimórficas vuelven a ser una simple proposición. Sin embargo, no puedo encontrar ninguna propuesta para ello. :(
fuente
Las lambdas de C ++ 11 no se pueden modelar como se indica en otras respuestas, pero
decltype()
parece ayudar cuando se usa una lambda dentro de una clase o función con plantilla.Huellas dactilares:
He descubierto que esta técnica es útil cuando se trabaja con código con plantilla, pero me doy cuenta de que todavía significa que las lambdas mismas no pueden ser creadas con plantillas.
fuente
T
funcionaría bien en lugar dedecltype(t)
en este ejemplo.En C ++ 11, las funciones lambda no pueden crearse plantillas, pero en la próxima versión del estándar ISO C ++ (a menudo llamado C ++ 14), se introducirá esta característica. [Fuente]
Ejemplo de uso:
Tenga en cuenta que aunque la sintaxis usa la palabra clave
auto
, la deducción de tipo no usará las reglas deauto
deducción de tipo, sino que usará las reglas de deducción de argumentos de plantilla. Consulte también la propuesta de expresiones lambda genéricas (y la actualización de esto).fuente
auto
deducción de tipos se definen específicamente para ser las mismas que las de latemplate
deducción de argumentos de función.Soy consciente de que esta pregunta es sobre C ++ 11. Sin embargo, para aquellos que buscaron en Google y aterrizaron en esta página, las lambdas con plantillas ahora son compatibles con C ++ 14 y reciben el nombre de Lambdas genéricas.
[info] La mayoría de los compiladores populares soportan esta característica ahora. Microsoft Visual Studio 2015 es compatible. Clang apoya. GCC apoya.
fuente
Me pregunto qué pasa con esto:
Utilicé un código similar como este, para generar una plantilla y me pregunto si el compilador optimizará la función de "ajuste".
fuente
Eche un vistazo a Boost.Phoenix para lambdas polimórficas: http://www.boost.org/doc/libs/1_44_0/libs/spirit/phoenix/doc/html/index.html No requiere C ++ 0x, por el camino :)
fuente
Hay una extensión gcc que permite plantillas lambda :
donde
_widgets
es unstd::tuple< fusion::pair<Key_T, Widget_T>... >
fuente
He estado jugando con la última
version 5.0.1
compilación de clang con la-std=c++17
bandera y ahora hay un buen soporte para los parámetros de tipo automático para lambdas:fuente
Aquí hay una solución que implica envolver la lamba en una estructura:
Para usar do:
El problema principal con esto (además del tipeo adicional) no puede incrustar esta definición de estructura dentro de otro método u obtener (gcc 4.9)
También intenté hacer esto:
Con la esperanza de poder usarlo así:
Pero me sale el error del compilador:
Así que esto no funciona ... pero incluso si compilara, sería de uso limitado porque aún tendríamos que poner el "uso de LamdaT" en el alcance del archivo (porque es una plantilla) que de alguna manera frustra el propósito de lambdas
fuente
No estoy seguro de por qué nadie más ha sugerido esto, pero puede escribir una función con plantilla que devuelva funciones lambda. Lo siguiente resolvió mi problema, la razón por la que vine a esta página:
Ahora, cuando quiero una función que tome un tipo dado de argumento (por ejemplo
std::string
), solo digoY ahora
f("any string")
vuelve1.0
.Ese es un ejemplo de lo que quiero decir con "función lambda con plantilla". (Este caso particular se usa para proporcionar automáticamente una función de ponderación inerte cuando alguien no quiere ponderar sus datos, sean cuales sean sus datos).
fuente