cpp-funciones-lambda

Qué son y cómo usar las funciones lambda en C++

En C++ una función lambda es una sintaxis compacta para definir funciones anónimas, sin necesidad de declararla de forma explícita como una función tradicional.

Estas funciones son especialmente útiles para operaciones simples y rápidas. Por ejemplo, cuando se trata de operaciones en colecciones, como filtrado, mapeo o reducción.

Si quieres aprender más sobre funciones Lambda
consulta el Curso de Introducción a la Programación leer más

Sintaxis de las funciones lambda

La sintaxis básica de una función lambda en C++ es la siguiente:

[captura](parametros) -> tipo_retorno { cuerpo }
  • Captura: Lista de variables del entorno que la lambda puede usar.
  • Parámetros: Lista de parámetros de entrada, separados por comas si hay más de uno.
  • Tipo de retorno: Tipo de valor que devuelve la lambda, opcional si el tipo es deducible.
  • Cuerpo: El código que se ejecuta cuando se invoca la lambda.

Ejemplo básico

Aquí tienes un ejemplo básico de una función lambda que suma dos números:

#include <iostream>

int main() {
    auto sumar = [](int x, int y) -> int {
        return x + y;
    };

    std::cout << "Suma: " << sumar(5, 3) << std::endl; // Output: 8

    return 0;
}

En este ejemplo,

  • La función lambda sumar toma dos parámetros x e y, y devuelve su suma.
  • La palabra clave auto se usa para deducir el tipo de la lambda, y -> int especifica el tipo de retorno.

Captura de variables

Las funciones lambda pueden capturar variables del contexto en el que se definen. Hay diferentes modos de captura:

  • Por valor (=): Captura una copia de las variables.
  • Por referencia (&): Captura las variables por referencia, permitiendo modificar su valor.
  • Mixta: Combinación de capturas por valor y por referencia.
#include <iostream>

int main() {
    int valor = 10;

    auto lambda = [valor]() {
        std::cout << "Valor: " << valor << std::endl;
    };

    lambda(); // Output: Valor: 10

    return 0;
}
#include <iostream>

int main() {
    int valor = 10;

    auto lambda = [&valor]() {
        valor++;
        std::cout << "Valor: " << valor << std::endl;
    };

    lambda(); // Output: Valor: 11
    std::cout << "Valor después de la lambda: " << valor << std::endl; // Output: Valor después de la lambda: 11

    return 0;
}

Uso en funciones de orden superior

Las funciones lambda pueden ser pasadas como argumentos a otras funciones que aceptan funciones o objetos funcionales.

Ejemplo con std::function:

#include <iostream>
#include <functional>

void Ejecutar(std::function<void()> func) {
    func();
}

int main() {
    auto mensaje = []() {
        std::cout << "Hola desde una función lambda" << std::endl;
    };

    Ejecutar(mensaje);

    return 0;
}

Lambdas captura de this

Las lambdas también pueden capturar this para acceder a los miembros de la clase desde dentro de la lambda.

#include <iostream>

class MiClase {
private:
    int valor;
public:
    MiClase(int v) : valor(v) {}
    void imprimirValor() {
        auto lambda = [this]() {
            std::cout << "Valor: " << valor << std::endl;
        };
        lambda();
    }
};

int main() {
    MiClase obj(42);
    obj.imprimirValor(); // Imprime 42
    return 0;
}

En este ejemplo, la lambda captura this para acceder al miembro valor de la clase MiClase.

Lambdas genericas

Desde C++14 las lambdas pueden ser genéricas, lo que permite trabajar con diferentes tipos de datos.

#include <iostream>

int main() {
    auto imprimir = [](auto dato) {
        std::cout << dato << std::endl;
    };
    imprimir(5);        // Imprime un entero
    imprimir(3.14);     // Imprime un flotante
    imprimir("Hola");   // Imprime una cadena de texto
    return 0;
}

En este ejemplo, la lambda imprimir es capaz de manejar diferentes tipos de datos gracias a su naturaleza genérica.

Ejemplos prácticos