¿Se pueden crear plantillas para las funciones lambda?

Resuelto Klaim asked hace 14 años • 14 respuestas

En C++ 11, ¿hay alguna manera de crear una plantilla para una función lambda? ¿O es intrínsecamente demasiado específico para utilizarlo como modelo?

Entiendo que puedo definir una clase/functor con plantilla clásica, pero la pregunta es más bien: ¿el lenguaje permite crear plantillas de funciones lambda?

Klaim avatar Aug 26 '10 21:08 Klaim
Aceptado

ACTUALIZACIÓN 2018: C++20 vendrá con lambdas conceptualizadas y con plantillas. 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.


Tal como está (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 dificultaron esta situación de código:

template <Constraint T>
void foo(T x)
{
    auto bar = [](auto x){}; // imaginary syntax
}

En una plantilla restringida sólo puedes llamar a otras plantillas restringidas. (De lo contrario, no se podrían verificar las restricciones). ¿Se puede fooinvocar bar(x)? ¿Qué restricciones tiene lambda (después de todo, su parámetro es solo una plantilla)?

Los conceptos no estaban preparados para abordar este tipo de cosas; requeriría más cosas como late_check(donde el concepto no se verificaba hasta que se invocaba) y esas cosas. Lo más sencillo era dejarlo todo y ceñirse a lambdas monomórficas.

Sin embargo, con la eliminación de conceptos de C++0x, las lambdas polimórficas vuelven a ser una propuesta simple. Sin embargo, no encuentro ninguna propuesta al respecto. :(

GManNickG avatar Aug 26 '2010 19:08 GManNickG

En C++20 esto es posible usando la siguiente sintaxis:

auto lambda = []<typename T>(T t){
    // do something
};
shilch avatar Jul 16 '2020 10:07 shilch

Las lambdas de C++ 11 no pueden tener plantillas como se indica en otras respuestas, pero decltype()parece ayudar cuando se usa una lambda dentro de una clase o función con plantilla.

#include <iostream>
#include <string>

using namespace std;

template<typename T>
void boring_template_fn(T t){
    auto identity = [](decltype(t) t){ return t;};
    std::cout << identity(t) << std::endl;
}

int main(int argc, char *argv[]) {
    std::string s("My string");
    boring_template_fn(s);
    boring_template_fn(1024);
    boring_template_fn(true);
}

Huellas dactilares:

My string
1024
1

Descubrí que esta técnica ayuda cuando se trabaja con código con plantilla, pero me doy cuenta de que aún significa que las lambdas mismas no pueden tener plantilla.

Joel avatar Aug 08 '2013 19:08 Joel

En C++11, las funciones lambda no pueden tener 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:

auto get_container_size = [] (auto container) { return container.size(); };

Tenga en cuenta que, aunque la sintaxis utiliza la palabra clave auto, la deducción de tipos no utilizará las reglas de autodeducción de tipos, sino que utilizará las reglas de deducción de argumentos de plantilla. Consulte también la propuesta para expresiones lambda genéricas (y la actualización de esta).

Timo Türschmann avatar Nov 18 '2013 11:11 Timo Türschmann