Лямбда-выражения и их тип

Лямбда-выражения (или просто лямбды) в C++ представляют собой удобный способ создания анонимных функций внутри кода. Они позволяют определять функции на месте и использовать их там же, где они были определены. Тип лямбды зависит от того, какие параметры она принимает и что она возвращает.

Синтаксис лямбда-выражений (лучше см. после всего остального)

Общий формат лямбда-выражения выглядит следующим образом:

[capture list] (parameters) -> return_type {
    // тело функции
    // return expression (необязательно)
};
  • capture list: список захвата переменных из внешней области видимости. Опциональная часть.
  • parameters: параметры функции, которые принимает лямбда.
  • return_type: тип возвращаемого значения функции (может быть опущен, если функция не возвращает значения).
  • тело функции: блок кода, который выполняется при вызове лямбда-функции.

Примеры лямбда-выражений

  1. Пример без параметров и возвращаемого значения:
[] {
    cout << "Hello, Lambda!" << endl;
};
  1. Пример с параметрами и возвращаемым значением:
[](int a, int b) -> int {
    return a + b;
};

Область захвата

Область захвата определяет доступность переменных из внешнего контекста (таких как локальные переменные функции или глобальные переменные) в теле лямбда-выражения. В C++ есть три способа захвата переменных:

  1. Захват по значению: Захват переменной копирует ее текущее значение в момент создания лямбда-выражения.
int a = 10;
auto lambda1 = [a] {
    cout << "Захваченное значение: " << a << endl;
};
  1. Захват по ссылке: Захват переменной по ссылке позволяет лямбде изменять значение переменной во внешнем контексте.
int b = 5;
auto lambda2 = [&b] {
    cout << "Захваченная ссылка: " << b << endl;
};
  1. Неявный захват: Захват переменных, которые используются в теле лямбды, но не указаны в списке захвата.
int c = 15;
auto lambda3 = [=] {
    cout << "Неявно захваченное значение: " << c << endl;
};
  1. Неявный захват по ссылке: Захват переменных по ссылке, которые используются в теле лямбды, но не указаны в списке захвата.
int d = 20;
auto lambda4 = [&] {
    cout << "Неявно захваченная ссылка: " << d << endl;
};

Особенности применения лямбда-функций

  • Удобство и компактность: Лямбда-выражения позволяют определять функции на лету внутри кода, что упрощает написание анонимных функций для различных задач.

  • Использование в алгоритмах: Часто лямбды используются вместе с алгоритмами стандартной библиотеки C++, такими как std::for_each, std::sort, std::transform и другими, для применения операций к элементам контейнеров.

#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
 
int main() {
    vector<int> nums = {3, 1, 4, 1, 5, 9, 2, 6, 5};
 
    // Пример: сортировка вектора с использованием лямбда-функции
    sort(nums.begin(), nums.end(), [](int a, int b) {
        return a > b; // сортировка по убыванию
    });
 
    // Вывод отсортированного вектора
    for (auto num : nums) {
        cout << num << " ";
    }
    cout << endl;
 
    return 0;
}
  • Захват переменных: Правильный выбор способа захвата переменных важен для корректной работы лямбды. Захваченные переменные должны быть корректно доступны во время выполнения лямбды, учитывая их жизненный цикл и возможные изменения.

  • Понимание контекста: Лямбда-выражения захватывают переменные из внешнего контекста на момент создания. Изменения в захваченных переменных во внешнем контексте после создания лямбды не отражаются внутри лямбды, если она захватила переменную по значению (copy capture).