Лямбда-выражения
Лямбда-выражение (лямбда-функция, анонимная функция) - функция без имени
Синтаксис:
[захват контекста](параметры) { реализация, тело };
Возвращаемый тип по умолчанию определяется по return лямбда-функции, однако его можно указать явно:
[]()->int {};
Пример (передача анонимной функции в функцию):
void DoWork(std::function<void(int)> func)
{
func(5);
}
// === 1 ===
std::function <void(int)> f;
f = [](int) { std::cout << "Anonymous\n"; };
DoWork(f);
// === 2 ===
DoWork([](int) { std::cout << "Anonymous\n"; } );
Какая же от этого польза? Бывают такие функции, которые будут использованы только в одном месте и нигде больше, однако они очень сильно захламляют пространтво имён своими названиями, соответственно в таких местах может быть выгоднее использовать лямбда-функции.
Захват переменных в контекст
Контекст лямбда-функции:
int a = 0;
[]()
{
// все это пространство имён изолировано
// от всего что вне этого пространства.
// Таким образом мы не можем работать с
// переменными вне контекста функции
a = 5; // нельзя
};
Что бы работать с переменными, которые находятся вне контекста анонимной функции их нужно захватить:
auto f = [a, b]() {}
- по значению (только для чтения, изменять переменную нельзя)auto f = [&a, &b]() {}
- по ссылке (можно изменять)auto f = [=]() {}
- захватить все что вне контекста по значениюauto f = [&]() {}
- захватить все что вне контекста по ссылкеauto f = [a, b]() mutable
- создавать локальные переменные внутри функции (как передача по значению в обычную функцию)auto f = [&a]() mutable
- mutable никак не влияет в данном случае, передача по ссылкеauto f = [this]()
- захватить экземпляр класса (что бы внутри метода можно было обращаться к другим методам и полям)
Начиная с С++14 на лямбда-функции можно ссылаться используя auto:
auto f = [&p](int a) { p = 5; };
f(5);