C++ Captura por valor


Ejemplo

Si especifica el nombre de la variable en la lista de captura, lambda la capturará por valor. Esto significa que el tipo de cierre generado para la lambda almacena una copia de la variable. Esto también requiere que el tipo de variable sea construible por copia :

int a = 0;

[a]() {
    return a;   // Ok, 'a' is captured by value
};
C ++ 14
auto p = std::unique_ptr<T>(...);

[p]() {         // Compile error; `unique_ptr` is not copy-constructible
    return p->createWidget(); 
};

A partir de C ++ 14, es posible inicializar variables en el lugar. Esto permite mover solo tipos para ser capturados en la lambda.

C ++ 14
auto p = std::make_unique<T>(...);

[p = std::move(p)]() {
    return p->createWidget(); 
};

Aunque una lambda captura variables por valor cuando se les da su nombre, tales variables no pueden modificarse dentro del cuerpo lambda por defecto. Esto se debe a que el tipo de cierre coloca el cuerpo lambda en una declaración de operator() const .

La const aplica a los accesos a las variables miembro del tipo de cierre, y las variables capturadas que son miembros del cierre (todas las apariencias de lo contrario):

int a = 0;

[a]() {
    a = 2;      // Illegal, 'a' is accessed via `const`

    decltype(a) a1 = 1; 
    a1 = 2; // valid: variable 'a1' is not const
};

Para eliminar la const , debe especificar la palabra clave mutable en la lambda:

int a = 0;

[a]() mutable {
    a = 2;      // OK, 'a' can be modified
    return a;
};

Debido a que a se capturó por valor, cualquier modificación realizada al llamar a la lambda no afectará a . El valor de a se copió en la lambda cuando se construyó, por lo que la copia de a de la lambda está separada de la variable externa a .

int a = 5 ; 
auto plus5Val = [a] (void) { return a + 5 ; } ; 
auto plus5Ref = [&a] (void) {return a + 5 ; } ; 

a = 7 ; 
std::cout << a << ", value " << plus5Val() << ", reference " << plus5Ref() ;
// The result will be "7, value 10, reference 12"