Почему член данных не может быть в списке захвата лямбда
У меня есть класс foo, который имеет bar как переменную-член.
В другой членной функции класса я пишу лямбда-функцию:
[bar](void){}
Но я не могу включить bar в список захвата. Почему это?
Ответ 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, полностью автономен и не имеет таких проблем жизни.