Подтвердить что ты не робот

С++ lambda - переменная элемента захвата

У меня есть класс, который имеет указатель на функцию ядра, который может меняться извне.

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

}

Как я могу добиться поведения, которое "представлено", например. читать переменные класса внутри лямбда. Я могу обойти его, пропуская f внутри и напишу f.bar.i, но это не очень хорошее решение.

4b9b3361

Ответ 1

В С++ 14 вы можете записать его как

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

Если у вас нет С++ 14, вы можете альтернативно создать другую переменную,

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

Хотя нет ничего плохого в передаче f и написании f.bar.i.

Ответ 2

Кажется, что вы не можете этого сделать. Нет никакой конструкции для создания функции-члена лямбда.

Но вы, вероятно, можете следовать предложению @KerrekSB и в дополнение к этой отправке вызов еще получить функцию-член:

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()

Обратите внимание, что вы не можете назвать оба поля kernel.

Ответ 3

Лямбда-функция не знает о я или Bar. Как он мог это знать? Вам нужно передать ссылку. Если вы определяете тело функции по-разному, чтобы вы могли передать я в качестве параметра, и вы вызываете его внутри класса, вы должны получить то, что хотите.