Перейти к содержанию

Последнее обновление:2026-10-12

Лямбда-выражения в C++20 (часть 1)

Шаблоны lambda в C++20

C++14 поддерживает обобщённые лямбда-выражения, что позволяет лямбде принимать параметры произвольных типов, например:

auto func = [](auto a, auto b) {
    return a + b;
};

Оно разворачивается в:

struct Func {
    template <typename T1, typename T2>
    auto operator()(T1 a, T2 b) const {
        return a + b;
    }
};

Однако невозможно получить следующие варианты разворота:

Первый: одинаковые типы

template <class T>
auto operator()(T t1, T t2) const;

Второй: только std::array

template <class T, std::size_t N>
auto operator()(std::array<T, N> const &) const; 

Третий: без выведения

template <class T>
auto operator()() const;

Лямбды C++14 хороши, но C++20 позволяет легко реализовать и эти случаи. C++20 разрешает лямбда-выражениям использовать шаблонные типовые параметры в определении; базовый синтаксис таков:

[]<typename T>(){}

Далее на нескольких примерах покажем, в чём выгода.

1.Ограничение типа

В примере наподобие приведённого ниже в C++14 мы могли бы написать такой код, однако при использовании передаваемое внутрь значение — не обязательно vector, и тогда поведение будет отличаться от ожидаемого, что приведёт к ошибкам.

auto print = [](auto vec) {
  for (auto x : vec) {
    std::cout << x << std::endl;
  }
};

После C++20 мы можем ограничить тип:

auto print2 = []<typename T>(std::vector<T>& vec){
    //使用 std::vector<T> 执行操作
};

Тогда вопрос — интервью-задача: знаете ли вы, как в C++14 ограничиться vector'ом и при этом гарантировать безопасность?

2.Идеальная передача (perfect forwarding)

В C++20 вы можете очень легко использовать идеальную передачу, например:

auto lambdaFunc = []<typename T>(T&& number) {
  processFunction(std::forward<T>(number));
};

Тогда вопрос: в чём преимущество по сравнению с C++14? Или иначе: что нужно было делать для реализации идеальной передачи в C++14?

На этом раздел закончен

Похожие темы

Комментарии