💡 Resumen:Lambda en C++20 (parte 1): sintaxis de plantillas y restricciones de tipo, y cómo el deducing this de C++23 convierte las lambdas recursivas en una línea sin std::function.
Última actualización:2026-10-24
Expresiones lambda de C++20 (parte 1)¶
Plantillas lambda en C++20¶
C++14 soporta expresiones lambda genéricas, lo que permite que una lambda acepte parámetros de cualquier tipo, por ejemplo:
Se expande a:
struct Func {
template <typename T1, typename T2>
auto operator()(T1 a, T2 b) const {
return a + b;
}
};
Pero no es capaz de lograr las siguientes expansiones:
Primera: el mismo tipo
Segunda: solo std::array
Tercera: sin deducción
Las lambdas de C++14 están muy bien, pero C++20 nos permite implementar estos casos con facilidad. C++20 permite que las expresiones lambda usen parámetros de tipo plantilla en su definición; he aquí la sintaxis básica:
A continuación, varios ejemplos ilustran sus ventajas.
1.Restricción de tipos¶
En un ejemplo como el siguiente, en C++14 podríamos escribir este código, pero lo que se pasa al usarlo no tiene por qué ser un vector, de modo que el comportamiento se desviaría de lo esperado y produciría errores.
A partir de C++20, podemos restringir su tipo:
Entonces surge la pregunta, y con ella una pregunta de entrevista: ¿sabes cómo garantizar la seguridad en C++14 para restringir un vector?
2.Reenvío perfecto¶
En C++20 puedes usar el reenvío perfecto con mucha facilidad, por ejemplo:
Entonces la pregunta es: frente a C++14, ¿qué ventaja tiene? Dicho de otro modo, ¿qué hacía falta para implementar el reenvío perfecto en C++14?
Fin de esta sección
Lambdas recursivas con deducing this (C++23)¶
Una lambda normal no puede nombrarse a sí misma, así que la recursión significaba guardar la lambda en un std::function (asignación, indirección) o envolverla en un combinador-Y (ingenioso, ilegible). Los parámetros de objeto explícitos de C++23 —la misma característica deducing this— lo resuelven con elegancia: la lambda se recibe a sí misma como primer parámetro:
// C++23 explicit object parameter: the lambda receives itself
auto factorial = [](this auto self, int n) -> long long {
return n <= 1 ? 1 : n * self(n - 1);
};
static_assert(factorial(10) == 3628800);
// before C++23 you needed std::function (heavy) or a Y-combinator (clever)
El parámetro self se deduce en cada llamada, así que la recursión genérica también funciona: una lambda puede recursar sobre cualquier tipo, y dos lambdas pueden llamarse mutuamente pasándose entre sí. Como el compilador ve a través de self, estas llamadas se inlinean como si hubieras escrito una función con nombre.
Soporte de compiladores: GCC 14+, Clang 18+, MSVC desde VS 2022 17.2 — compila con -std=c++23.
Preguntas frecuentes¶
¿Cómo escribo una lambda recursiva en C++?¶
Desde C++23, dale un parámetro de objeto explícito: [](this auto self, int n) { ... self(n-1) ... }. Antes, toca std::function, un combinador-Y, o simplemente una función con nombre.
¿La lambda recursiva con deducing this es tan rápida como una función normal?¶
En la práctica, sí: el compilador especializa la llamada a través de self y puede inlinearla, a diferencia de la llamada indirecta de std::function que exigía la recursión pre-C++23.
¿Funciona deducing this con lambdas genéricas?¶
Sí. self se deduce como auto&& en cada llamada, así que la misma lambda recursa sobre distintos tipos, y dos lambdas pueden incluso llamarse mutuamente pasándose entre sí.
Temas relacionados¶
- Introducción a las corrutinas de C++20 | C++那些事
- C++20 channel en la práctica | C++那些事
- Conceptos Concepts de C++20 | C++那些事
- constexpr y la expresión coma en C++20 | C++那些事
- Orden de bytes endian en C++20 | C++那些事
- Módulos Modules de C++20 | C++那些事
- La biblioteca Ranges de C++20 | C++那些事
- Diseño y trampas de std::span en C++20 | C++那些事
- Guía de las novedades de C++20 | C++那些事
- C++20 [[likely]] y [[unlikely]] | C++那些事