Почему член данных не может быть в списке захвата лямбда
У меня есть класс 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
, полностью автономен и не имеет таких проблем жизни.