sintaxis programacion lambdas expresiones aprender c++ lambda c++11

programacion - Captura de C++ 11 lambda por capturas de valor en el punto de declaración



lambda sintaxis (3)

El problema es que su función de impresión está capturando por valor y no por referencia.

#include <iostream> int main(int argc, char **argv){ int value = 0; auto incr_value = [&value]() { value++; }; auto print_value = [ value]() { std::cout << value << std::endl; }; auto print_valueref = [ &value]() { std::cout << value << std::endl; }; incr_value(); print_value(); print_valueref(); return 0; }

Salidas 0 y 1 como se esperaba. El primero se captura por valor e imprime el valor en el punto de captura; el segundo captura la referencia y luego imprime su valor.

El siguiente código imprime 0, pero espero ver un 1. Mi conclusión es que las funciones de lambda no se invocan al pasar efectivamente los parámetros capturados a las funciones, lo cual es más intuitivo. ¿Estoy en lo cierto o me estoy perdiendo algo?

#include <iostream> int main(int argc, char **argv){ int value = 0; auto incr_value = [&value]() { value++; }; auto print_value = [ value]() { std::cout << value << std::endl; }; incr_value(); print_value(); return 0; }


Las funciones de Lambda se invocan pasando realmente los parámetros capturados a la función.

value es igual a 0 en el punto donde se define lambda (y se captura el value ). Como está capturando por valor, no importa lo que haga para value después de la captura.

Si hubiera capturado el value por referencia, vería un 1 impreso porque aunque el punto de captura sigue siendo el mismo (la definición lambda) estaría imprimiendo el valor actual del objeto capturado y no una copia creada cuando fue capturado


Sí, las capturas se realizan en el punto en que se declara la lambda, no cuando se llama. Piense en una lambda como un objeto de función cuyo constructor toma las variables capturadas como parámetros y las asigna a sus correspondientes variables miembro (ya sean valores o referencias, dependiendo del modo de captura). La llamada real de la lambda no tiene magia, es solo una llamada al operator() regular operator() del objeto de función subyacente.

Capturar cosas en el punto de llamada no tendría mucho sentido. ¿Qué se capturaría si la lambda se devolviera o pasara como parámetro a otra función y se llamara allí? En realidad, hay idiomas que se comportan de esta manera: si se refiere a una variable x en una función, se supone que hace referencia a cualquier variable llamada x actualmente en alcance en el punto de llamada. Esto se llama alcance dinámico. La alternativa, utilizada por la mayoría de los idiomas porque hace que el razonamiento sobre los programas sea mucho más simple, se denomina ámbito léxico.

http://en.wikipedia.org/wiki/Lexical_scoping#Lexical_scoping_and_dynamic_scoping