Martin Perry
Martin Perry

Reputation: 9527

C++ lambda - capture member variable

I have a class that has function pointer to kernel function, that can change from outside.

class Bar 
{
   public:
     int i;
}

class Foo 
{
   public:
     std::function<double()> kernel;
     Bar bar;         
};

int main()
{

  Foo f;
  f.kernel = []() -> double { return i * i; }; //this is not working obviously

}

How can I achieve behaviour that is "presented", eg. read class variables inside lambda. I can bypass it by passing f inside and write f.bar.i, but that is not very nice solution.

Upvotes: 18

Views: 21128

Answers (3)

aslg
aslg

Reputation: 1974

In C++14 you can write it as,

f.kernel = [&i = f.bar.i]() -> double { return i * i; };

If you don't have C++14, you can alternatively create another variable,

int &i = f.bar.i;
f.kernel = [&i]() -> double { return i*i; };

Though there's nothing wrong with passing f and writing f.bar.i.

Upvotes: 25

Gerhard Stein
Gerhard Stein

Reputation: 1563

The lambda function does not know about i or Bar. How could it know? You need to pass a Reference. If you define the function body differently so you can pass i as parameter and you call it within the class you should get what you want.

Upvotes: 0

dhke
dhke

Reputation: 15388

It seems that you cannot do so. There is no construct to create a member function lambda.

But you probably can follow @KerrekSB's suggestion and in addition to that dispatch the call to still get the member function:

class Foo 
{
public:
    double kernel()
    {
        _kernel(*this);
    }

    std::function<double(Foo &)> _kernel;
};


Foo f;
f._kernel = [](Foo &f) -> double { return f.i * f.i; };
f.kernel()

Note that you cannot name both fields kernel.

Upvotes: 8

Related Questions