Синтаксис шаблона С++ std:: function-like

В С++ 11 вы можете создать экземпляр std:: function следующим образом:

std::function<void(int)> f1;
std::function<int(std::string, std::string)> f2;
//and so on

Но пока есть много информации о вариативных шаблонах в Интернете, я не могу найти статей о том, как писать std:: function-like template, который принимал бы аргументы в скобках. Может ли кто-нибудь объяснить синтаксис и его ограничения или хотя бы указать на существующее объяснение?

Ответ 1

В этом нет ничего особенного, это обычный тип функции. Когда вы объявляете такую ​​функцию:

int foo(char a, double b)

Тогда его тип int (char, double). Одним из способов "разворачивания" отдельных типов аргументов и типа возврата является использование частичной специализированности шаблонов. В принципе, std::function выглядит примерно так:

template <class T>
struct function; // not defined

template <class R, class... A>
struct function<R (A...)>
{
  // definition here
};

Ответ 2

В значительной степени, как и любой другой шаблон, поскольку int(std::string, std::string) - это просто тип.

Вот действительно наивный пример, который компилируется:

template <typename FType>
struct Functor
{
   Functor(FType* fptr) : fptr(fptr) {}

   template <typename ...Args>
   void call(Args... args)
   {
      fptr(args...);
   }

private:
   FType* fptr;
};

void foo(int x, char y, bool z) {}

int main()
{
   Functor<void(int, char, bool)> f(&foo);
   f.call(1, 'a', true);
   //f.call(); // error: too few arguments to function
}

В действительности у вас будет специализация FType ReturnType(ArgTypes...), хотя мой наивный пример уже даст вам необходимую проверку, если вы попытаетесь вызвать его совместимыми способами.