Ответ
Лямбда-выражения (начиная с C++11) предоставляют краткий синтаксис для создания анонимных функциональных объектов (замыканий) прямо в месте использования. Они кардинально упрощают работу с алгоритмами STL и асинхронными операциями, избавляя от необходимости писать отдельные функторы или функции.
Базовый синтаксис: [захват](параметры) -> возвращаемый_тип { тело }. Возвращаемый тип часто выводится автоматически.
1. Использование с алгоритмами STL (самый частый случай):
std::vector<int> numbers = {1, 5, 3, 8, 2};
// Сортировка по убыванию
std::sort(numbers.begin(), numbers.end(),
[](int a, int b) { return a > b; });
// Поиск первого четного числа
auto it = std::find_if(numbers.begin(), numbers.end(),
[](int n) { return n % 2 == 0; });
// Подсчет чисел, больших заданного порога
int threshold = 4;
int count = std::count_if(numbers.begin(), numbers.end(),
[threshold](int n) { return n > threshold; });
std::cout << count << " numbers are greater than " << threshold << std::endl;
2. Захват переменных из окружающего контекста: Способ передачи внешних данных в лямбду.
int base = 100;
std::string prefix = "Result: ";
// Захват по значению [base, prefix]
auto adder = [base, prefix](int x) {
return prefix + std::to_string(base + x);
};
// Захват по ссылке [&base, &prefix] - осторожно с временами жизни!
// Захват всего контекста по значению [=] или по ссылке [&] (не рекомендуется)
3. Использование в асинхронных задачах (std::async, потоки):
#include <future>
#include <thread>
int computeSomething() { /* долгий расчет */ return 42; }
// Запуск вычисления в отдельном потоке
std::future<int> result = std::async(std::launch::async, []() {
return computeSomething();
});
// Делаем что-то ещё в основном потоке
std::cout << "Waiting for result..." << std::endl;
// Получаем результат (блокируемся, если не готов)
int value = result.get();
std::cout << "Result is: " << value << std::endl;
Ключевые преимущества:
- Инкапсуляция логики: Код обработки находится прямо рядом с вызовом алгоритма, улучшая читаемость.
- Гибкость: Легко создавать специализированные операции "на лету".
- Производительность: Компилятор часто может заинлайнить тело лямбды, устраняя накладные расходы на вызов функции.
Эволюция в стандартах: C++14 добавил обобщенные лямбды (auto в параметрах), C++17 — constexpr лямбды, C++20 — лямбды в unevaluated контекстах и шаблонные параметры для лямбд.