Назад к вопросам
Middle
117
questionbank

Расскажите о лямбда-функциях в C/C++.

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Лямбда-функции — это безымянные inline-функции, которые можно определить и использовать непосредственно в точке вызова. Появились в C++11.

Синтаксис:

[capture list](parameter list) -> return type {
    // тело лямбда-функции
}
  • [capture list] (список захвата) — определяет, какие внешние переменные доступны внутри лямбды и как они захватываются (по значению [var] или по ссылке [&var]). [=] захватывает все по значению, [&] — все по ссылке. [] означает отсутствие захвата.
  • (parameter list) (список параметров) — аналогичен списку параметров обычной функции.
  • -> return type (тип возвращаемого значения) — указывает тип возвращаемого значения. Может быть опущен, если тип может быть выведен компилятором (начиная с C++14).
  • {} (тело лямбда-функции) — содержит исполняемый код лямбды.

Примеры использования:

Сортировка с пользовательским критерием:

#include <vector>
#include <algorithm>
#include <iostream>

int main() {
    std::vector<int> numbers = {5, 2, 8, 1, 9};
    
    // Сортировка по убыванию с использованием лямбды
    std::sort(numbers.begin(), numbers.end(), [](int a, int b) {
        return a > b; // Критерий для убывания
    });

    for (int n : numbers) {
        std::cout << n << " ";
    }
    std::cout << std::endl; // Вывод: 9 8 5 2 1

    return 0;
}

Использование захвата:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    int threshold = 5;
    std::vector<int> numbers = {1, 7, 3, 8, 2, 6};
    
    // Подсчет элементов больше threshold, захватывая threshold по значению
    int count = std::count_if(numbers.begin(), numbers.end(), [threshold](int n) {
        return n > threshold;
    });
    
    std::cout << "Count of numbers > " << threshold << ": " << count << std::endl; // Вывод: Count of numbers > 5: 3

    return 0;
}

Захват по ссылке для модификации внешней переменной (требует mutable для захвата по значению):

#include <iostream>

int main() {
    int value = 10;
    
    // Захват value по ссылке, чтобы изменить его внутри лямбды
    auto modify_value = [&value]() {
        value += 5;
    };

    modify_value();
    
    std::cout << "Modified value: " << value << std::endl; // Вывод: Modified value: 15

    return 0;
}

Преимущества:

  • Краткость и наглядность: Упрощают код, когда функция нужна только в одном месте.
  • Местоположение: Определяются там, где используются, улучшая локальность кода.
  • Захват переменных: Легкий доступ к переменным из окружающего контекста.
  • Эффективность: Часто компилируются как inline-функции, избегая накладных расходов на вызов.

Недостатки:

  • Могут усложнить отладку, если используются в сложном контексте.
  • Чрезмерное использование для сложных задач может сделать код менее читаемым.