C++ lambda: how to 'freeze' values of local variables?

  • A+

In the code below, class A has a lambda as a data member, and a getter to this lambda. Is it possible to 'freeze' the local variables of the lambda to the values that are present when the lambda is returned by the getter?

In other words specifically in this example, is it possible to make the code print 6 instead of 150 even after the value of myA.b is changed?

#include <iostream> #include <functional>  class A {     double b;      std::function<double(double)> myFunction = [=] (double x)     {         double localb = b;         return localb*x;     };  public:      void set_b(double value){b = value;};      std::function<double(double)> get_myFunction(){return myFunction;};     };  int main() {     A myA;     myA.set_b(2.0);      std::function<double(double)> retrievedFunction = myA.get_myFunction();      myA.set_b(50.0);      std::cout << retrievedFunction(3.0) << std::endl;      return 0; } 


You have two issues.

One is related to the answer here: C++11 lambdas: member variable capture gotcha, namely that the lambda captures the member variable via this, which is the only way to do it. That means you'll always get the current value of the member b.

Even if you fix this, myFunction is created once at the beginning, meaning it would capture the current (uninitialized!) value of b at creating time.

What you need is to generate the lambda exactly when get_myFunction() is called, and to have it capture the current value of b:

class A {     double b; public:      void set_b(double value){b = value;};      std::function<double(double)> get_myFunction() {         double localb = b;         return ([=] (double x) { return localb*x; });     } }; 


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: