Ответ
Поля (или захват переменных) позволяют лямбда-функции в C++ получать доступ к данным из окружающей области видимости. Это ключевой механизм для создания замыканий.
Основные способы захвата:
- По значению
[=]или[x]: Создаётся копия переменной на момент создания лямбды. Изменения внутри лямбды не затрагивают оригинал. - По ссылке
[&]или[&x]: Лямбда работает непосредственно с исходной переменной. Изменения внутри лямбды видны снаружи. - Инициализирующий захват (C++14)
[x = std::move(obj)]: Позволяет перемещать или инициализировать захватываемые объекты.
Пример:
int counter = 0;
std::string msg = "Hello";
// Захват counter по ссылке, msg по значению
auto lambda = [&counter, msg]() {
++counter; // Меняет исходный counter
std::cout << msg << " called " << counter << " timesn"; // msg - копия
};
lambda(); // Вывод: Hello called 1 times
lambda(); // Вывод: Hello called 2 times
// Исходная msg осталась "Hello"
Критические нюансы:
- Время жизни: Захват по ссылке опасен, если лямбда (например, сохранённая в
std::function) переживёт захваченную переменную, что приведёт к неопределённому поведению. - По умолчанию
const: Лямбда, захватившая переменные по значению, по умолчанию являетсяconst. Для модификации таких копий требуется спецификаторmutable. this: Для захвата членов класса внутри метода используется[this]или[*this](C++17, захват копии объекта).