Volver a la página principal
lunes 23 diciembre 2024
8

¿Cómo usar [this] en una lambda en C++?

En C++, el uso de [this] en una lambda permite capturar el puntero this de la clase que contiene la lambda. Esto es útil para acceder a los miembros y funciones de la clase desde dentro de la lambda. Es especialmente común en casos donde las lambdas se utilizan como callbacks o manejadores en programación orientada a objetos.

¿Qué es [this] en una lambda en C++?

En C++, las lambdas pueden capturar variables del ámbito en que se definen mediante un capture list (lista de captura). [this] captura el puntero this, permitiendo que la lambda acceda a los miembros de la instancia de la clase desde donde se invoca.

Ejemplo básico:

#include <iostream>
#include <functional>

class Ejemplo {
public:
    int valor = 42;

    void mostrarLambda() {
        auto lambda = [this]() {
            std::cout << "Valor: " << this->valor << std::endl;
        };
        lambda();
    }
};

int main() {
    Ejemplo obj;
    obj.mostrarLambda();
    return 0;
}

Salida:

Valor: 42

¿Cuándo usar [this]?

1. Acceso a miembros de la clase: Permite usar variables y funciones miembro dentro de una lambda.

2. Trabajar con callbacks: Es útil cuando se pasan lambdas como argumentos que necesitan contexto de la clase.

3. Evitar capturas innecesarias: Al usar [this], no es necesario capturar cada miembro individualmente.

Ejemplo práctico: Uso en un callback

#include <iostream>
#include <functional>

class Temporizador {
private:
    int contador = 0;

public:
    void iniciar(std::function<void()> callback) {
        contador++;
        callback();
    }

    void ejecutar() {
        iniciar([this]() {
            std::cout << "Contador actual: " << this->contador << std::endl;
        });
    }
};

int main() {
    Temporizador temp;
    temp.ejecutar(); // Contador actual: 1
    return 0;
}

Consideraciones importantes

1. Seguridad con el puntero this: Si la lambda capturando [this] se ejecuta después de que el objeto haya sido destruido, el comportamiento será indefinido. Para evitarlo, utiliza std::shared_ptr o std::weak_ptr para gestionar la vida útil del objeto.

Ejemplo con std::shared_ptr:

#include <iostream>
   #include <memory>
   #include <functional>

   class Ejemplo : public std::enable_shared_from_this<Ejemplo> {
   public:
       void ejecutar() {
           auto self = shared_from_this();
           auto lambda = [self]() {
               std::cout << "Ejecutando de forma segura." << std::endl;
           };
           lambda();
       }
   };

   int main() {
       auto obj = std::make_shared<Ejemplo>();
       obj->ejecutar();
       return 0;
   }

2. Evitar capturas innecesarias: Si no necesitas capturar this, puedes usar una lambda sin captura ([]).

Referencias

Para más detalles sobre lambdas y capturas en C++, consulta la documentación oficial de C++.

Etiquetas:
cpp
Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer