¿Cuál es la necesidad de la plantilla lambda introducida en C ++ 20 cuando C ++ 14 ya tiene lambda genérica?

99

introdujo lambdas genéricas que hicieron posible escribir lo siguiente:

auto func = [](auto a, auto b){
    return a + b;
};
auto Foo = func(2, 5);
auto Bar = func("hello", "world");

Está muy claro que esta lambda genérica funcfunciona como lo funcharía una función con plantilla .

¿Por qué el comité de C ++ decidió agregar una sintaxis de plantilla para lamda genérico?

codificador3101
fuente
5
¿Qué sucede si necesita usar un tipo de plantilla diferente al de los argumentos o al tipo de retorno? ¿Y si se necesita dentro del cuerpo?
Un tipo programador
Me han dicho que este era un caso de uso interesante.
Max Langhof
Vea esto para una comparación de las diferentes versiones de lambda: modernescpp.com/index.php/more-powerful-lambdas-with-c-20
schoetbi hace

Respuestas:

115

Las lambdas genéricas de C ++ 14 son una forma genial de generar un functor con un operator ()aspecto similar a este:

template <class T, class U>
auto operator()(T t, U u) const;

Pero no así:

template <class T>
auto operator()(T t1, T t2) const; // Same type please

Ni así:

template <class T, std::size_t N>
auto operator()(std::array<T, N> const &) const; // Only `std::array` please

Ni de esta manera (aunque esto se vuelve un poco complicado de usar):

template <class T>
auto operator()() const; // No deduction

Las lambdas de C ++ 14 están bien, pero C ++ 20 nos permite implementar estos casos sin problemas.

Quentin
fuente
2
Agradable y conciso. Solo agregando esto: el primero (los mismos tipos) se puede resolver (auto a, decltype(a) b)en C ++ 14.
Sebastian Mach
13
@SebastianMach casi. Con esa solución bno se deduce, y su argumento se convertirá implícitamente al tipo de en su alugar.
Quentin
32

Dado que puede usar lambdas con plantilla en C ++ 20, puede restringir sus tipos de una manera más fácil que una expresión SFINAE:

auto lambda = []<typename T>(std::vector<T> t){};

Esta lambda funcionará solo con tipos de vector.

Antoine Morrier
fuente
8
¿Cómo se constevalrelaciona con la nueva sintaxis? Es genial y todo, pero no entiendo la relevancia.
StoryTeller - Unslander Monica
Es más una información sobre lo que C ++ 20 agrega a la expresión lambda que una respuesta a la pregunta
Antoine Morrier
24

La propuesta que fue aceptada en C ++ 20 tiene una sección de motivación extensa, con ejemplos. La premisa es esta:

Hay algunas razones clave por las que el autor considera insuficiente la sintaxis actual para definir lambdas genéricas. La esencia de esto es que algunas cosas que se pueden hacer fácilmente con plantillas de funciones normales requieren que se realicen saltos de aro significativos con lambdas genéricas, o no se pueden hacer en absoluto. El autor cree que las lambdas son lo suficientemente valiosas como para que C ++ las soporte tan bien como las plantillas de funciones normales.

A continuación hay bastantes ejemplos.

StoryTeller - Unslander Monica
fuente
21

El nuevo "sintaxis de la plantilla familiar" para lambdas introducidas en C ++ 20 marcas construye como  for_types y  for_range viable y de forma más legible en comparación con C ++ 17 alternativas.

(fuente: iteración en tiempo de compilación con C ++ 20 lambdas )

Otra cosa interesante que se puede hacer tanto en C ++ 14 como en C ++ 17 genéricas lambdas es llamar directamente  operator() pasando explícitamente un parámetro de plantilla:

C ++ 14:

   auto l = [](auto){ };
   l.template operator()<int>(0);

C ++ 20:

  auto l = []<typename T>(){ };
  l.template operator()<int>();

El ejemplo de C ++ 14 anterior es bastante inútil: no hay forma de hacer referencia al tipo proporcionado  operator() en el cuerpo de la lambda sin darle un nombre al argumento y usar  decltype. Además, nos vemos obligados a pasar un argumento aunque no lo necesitemos.

El ejemplo de C ++ 20 muestra cómo se puede acceder fácilmente a T en el cuerpo de la lambda y que ahora se puede crear una plantilla de forma arbitraria para una lambda nular. Esto será muy útil para la implementación de las construcciones en tiempo de compilación mencionadas anteriormente.

Hamza.S
fuente