Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ std::function-like template syntax

In C++11 you can instantiate std::function like this:

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

But while there is plenty of info on variadic templates on the web, I fail to find any articles on how to write std::function-like template which would accept parenthesized arguments. Could anyone please explain the syntax and its limitations or at least point to an existing explanation?

like image 325
Smiles Avatar asked Dec 22 '14 13:12

Smiles


People also ask

How do you declare a template function in C++?

To instantiate a template function explicitly, follow the template keyword by a declaration (not definition) for the function, with the function identifier followed by the template arguments. template float twice<float>( float original ); Template arguments may be omitted when the compiler can infer them.

Which one is suitable syntax for function template?

Which one is suitable syntax for function template? Explanation: Both class and typename keywords can be used alternatively for specifying a generic type in a template.

How do you call a function in a template?

A function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.

Is std :: function copyable?

Instances of std::function can store, copy, and invoke any CopyConstructible Callable target -- functions (via pointers thereto), lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.


2 Answers

There's nothing special about it, it's an ordinary function type. When you declare a function like this:

int foo(char a, double b)

Then its type is int (char, double). One way of "unwrapping" the individual argument types and return type is to use partial template specialisation. Basically, std::function looks something like this:

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

template <class R, class... A>
struct function<R (A...)>
{
  // definition here
};
like image 174
Angew is no longer proud of SO Avatar answered Dec 07 '22 16:12

Angew is no longer proud of SO


Pretty much like any other template, since int(std::string, std::string) is just a type.

Here's a really naive example that compiles:

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
}

In reality you'd have a specialisation on FType being ReturnType(ArgTypes...), though my naive example will already give you the validation you need if you try to invoke it in in compatible ways.

like image 25
Lightness Races in Orbit Avatar answered Dec 07 '22 17:12

Lightness Races in Orbit