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

Почему член данных не может быть в списке захвата лямбда

У меня есть класс foo, который имеет bar как переменную-член.

В другой членной функции класса я пишу лямбда-функцию:

[bar](void){}

Но я не могу включить bar в список захвата. Почему это?

4b9b3361

Ответ 1

Вы захватываете членов класса, говоря this в списке захвата. Это не имеет никакого отношения к тому, что член const.


Пример:

#include <iostream>

struct Foo
{
    const int a = 0;
    int b;
    Foo() : b{42} {
        auto f = [this]() { std::cout << a << " " << b << std::endl; };
//                ^^^^ 
        f();
    }
};

int main() {
    Foo x;
}

Ответ 2

Только объекты с автоматической продолжительностью хранения могут быть захвачены лямбдой в С++ 11 (то есть локальными переменными и параметрами функции). Если вам нужен эффект захвата элемента данных класса non-static, вы можете либо захватить указатель this, как в ответ Danvil:

auto f = [this]{ std::cout << a << std::endl; };

или кешировать значение члена данных в локальной переменной и зафиксировать это:

auto a = this->a;
auto f = [a]{ std::cout << a << std::endl; };

который будет более кратким в С++ 14:

auto f = [a = this->a]{ std::cout << a << std::endl; };

Выбор между этими двумя параметрами зависит от того, хотите ли вы сохранить значение a прямо сейчас, или если вы хотите получить значение a, когда вызывается лямбда. Обратите внимание, что в случае захвата this вы должны убедиться, что время жизни объекта-указателя охватывает время жизни лямбда-вызова на лямбда после уничтожения объекта, имеет поведение undefined. Более простой случай, который захватывает копию a, полностью автономен и не имеет таких проблем жизни.