Если вы заинтересовались и не можете дождаться выхода следующего стандарта С++, то обратитесь к документации для ranges, которая находится по адресу https://ericniebler.github.io/range-v3/.
Глава 4
Лямбда-выражения
В этой главе:
□ динамическое определение функций с помощью лямбда-выражений;
□ добавление полиморфизма путем оборачивания лямбда-выражений в конструкцию std::function
;
□ создание функций с помощью конкатенации;
□ создание сложных предикатов с помощью логической конъюнкции;
□ вызов нескольких функций с одними и теми же входными данными;
□ реализация transform_if
с применением std::accumulate
и лямбда-выражений;
□ генерация декартова произведения на основе любых входных данных во время компиляции.
Введение
Одной из важных новых функций C++11 были лямбда-выражения. В C++14 и C++17 они получили новые возможности, и это сделало их еще мощнее. Но что же такое лямбда-выражение?
Лямбда-выражения или лямбда-функции создают замыкания. Замыкание — очень обобщенный термин для ()
, с параметрами или без. Создание аналогичного объекта без лямбда-выражений до появления С++11 выглядело бы так:
#include
#include
int main() {
struct name_greeter {
std::string name; void operator()() {
std::cout << "Hello, " << name << '\n';
}
};
name_greeter greet_john_doe {"John Doe"};
greet_john_doe();
}
Экземпляры структуры name_greeter
, очевидно, содержат строку. Обратите внимание: тип этой структуры и объект не являются безымянными, в отличие от лямбда-выражений. С точки зрения замыканий можно утверждать, что они Hello, John Doe
", поскольку мы указали строку с таким именем.
Начиная с С++11 создавать подобные замыкания стало проще:
#include
int main() {
auto greet_john_doe ([] {
std::cout << "Hello, John Doe\n";
});
greet_john_doe();
}
На этом все. Целая структура name_greeter
заменяется небольшой конструкцией [] { /* сделать что-то */ }
, которая на первый взгляд выглядит странно, но уже в следующем разделе мы рассмотрим все возможные случаи ее применения.
Лямбда-выражения помогают поддерживать код
В текущей главе мы в значительной мере будем опираться на отдельные шаблоны
Динамическое определение функций с помощью лямбда-выражений
Применяя лямбда-выражения, можно инкапсулировать код, чтобы вызвать его позже или даже в другом месте, поскольку его разрешено копировать. Кроме того, можно инкапсулировать код несколько раз с несколько различающимися параметрами, при этом не нужно будет реализовывать новый класс функции для этой задачи.
Синтаксис лямбда-выражений выглядел новым в С++11, и к С++17 он несколько изменился. В этом разделе мы увидим, как сейчас выглядят лямбда-выражения и что они означают.
Как это делается