Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 | страница 36
>auto derefLess = // Функция сравнения в С++14,
> [](const auto& p1, // для значений, на которые
> const auto& p2) // указывает что угодно
> { return *p1 < *p2; }; // указателеобразное
Несмотря на всю крутость вы, вероятно, думаете, что можно обойтись и без >auto
для объявления переменной, которая хранит лямбда-выражение, поскольку мы можем использовать объект >std::function
. Это так, можем, но, возможно, это не то, что вы на самом деле подразумеваете. А может быть, вы сейчас думаете “А что это такое — объект >std::function
?” Давайте разбираться.
>std::function
— шаблон стандартной библиотеки С++11, который обобщает идею указателя на функцию. В то время как указатели на функции могут указывать только на функции, объект >std::function
может ссылаться на любой вызываемый объект, т.e. на все, что может быть вызвано как функция. Так же как при создании указателя на функцию вы должны указать тип функции, на которую указываете (т.e. сигнатуру функции, на которую хотите указать), вы должны указать тип функции, на которую будет ссылаться создаваемый объект >std::function
. Это делается с помощью параметра шаблона >std::function
. Например, для объявления объекта >std::function
с именем >func
, который может ссылаться на любой вызываемый объект, действующий так, как если бы его сигнатура была
>bool(const std::unique_ptr
> const std::unique_ptr
> // std::unique_ptr
следует написать следующее:
>std::function<bool(const std::unique_ptr
> const std::unique_ptr
Поскольку лямбда-выражения дают вызываемые объекты, замыкания могут храниться в объектах >std::function
. Это означает, что можно объявить С++11-версию >derefUPLess
без применения >auto
следующим образом:
>std::function
> const std::unique_ptr
> derefUPLess = [](const std::unique_ptr
> const std::unique_ptr
> { return *p1 < *p2; };
Важно понимать, что, даже если оставить в стороне синтаксическую многословность и необходимость повторения типов параметров, использование >std::function
— не то же самое, что использование >auto
. Переменная, объявленная с использованием >auto
и хранящая замыкание, имеет тот же тип, что и замыкание, и как таковая использует только то количество памяти, которое требуется замыканию. Тип переменной, объявленной как