Универсальный std::function для хранения универсального лямбда-выражения

Когда общая лямбда хранится как std::functionнам нужно предоставить конкретный тип, что-то вроде,

std::function<double(double)>

таким образом, привязка к определенному типу,

Следующая декларация:

std::function<auto(auto)>

выдает ошибку компилятора.

Я понимаю, что, начиная с C++14, auto может использоваться для хранения возвращаемого значения лямбда-выражения, но есть ли способ добиться этого при хранении лямбда-выражения в std::function?

2 ответа

Ты не можешь Даже с кастомом не написал std::function, Это фундаментальный предел стирания типа.

Интуитивно, шаблоны требуют информацию о типе, доступную в точке вызова функции, но стирают тип в std::function уничтожает эту информацию.

На более детальном уровне стирание типов работает путем сохранения набора операций независимо от типа во время компиляции, либо неявно с помощью виртуальных функций, либо явно с помощью указателей на функции. Шаблоны фактически представляют собой бесконечное семейство операций, поэтому их невозможно сохранить.

Если вы знаете фиксированный набор сигнатур функций, которые вы будете использовать, вы можете написать std::function,

Ты не можешь

Общий лямбда и std::function это совершенно разные вещи.

Вы можете грубо увидеть auto(auto) лямбда как не шаблонный класс с шаблоном operator(),

Что-то как

struct myUnnamedLambdaStruct
 {
   // ...

   template <typename T>
   auto operator() (T t) const 
    { /* .... */ };
 };

куда std::function() наоборот: это (специализация) шаблонный класс с не-шаблоном operator()

template <typename>
class function;

template <typename RetType, typename ... ArgTypes>
class function<RetType(ArgTypes...)>
 {
   // a lot of other members/methods

   public:
      RetType operator() (ArgTypes ... args) const
       { /* .... */ }
 };

Таким образом, общий лямбда-объект не содержит ни одного operator() но набор operator() где std::function объект содержит один operator(),

Вы можете "сохранить" общую лямбду в std::function но только исправление, один раз для всех, RetType и ArgTypes..., То есть: выбор одного operator(), в доступном наборе operator()и забывая обо всех остальных.

Другие вопросы по тегам