Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unpacking arguments of a functional parameter to a C++ template class

I have a question involving functional template arguments to template classes in C++.

I'd like to define a template class Foo taking a single template parameter Fun

   template <typename Fun>
   struct Foo {
      ...
   };

such that given a function like

   void bar(std::string a, float b, char c)
   {
      ...
   }

then Foo<bar>::args_t will be equivalent to a typedef for

   std::tuple<std::string, float, char>

Is this possible? (The use of std::tuple here is just for concreteness. More generally I'm wondering if it's possible to do something like pattern-matching on the arguments of a functional template parameter.)

The point is to avoid having to define Foo in a way like

   template Foo<typename A, typename B, typename C, typename D,
      D (*Fun)(A a, B b, C c)>
   struct Foo {
      typedef std::tuple<A,B,C>  args_t;
   };

which requires both committing to a fixed number of function arguments, and requiring the argument and return types of the function to be provided explicitly as template parameters. (Defining Foo using variadic templates could presumably solve the former issue, but what about the latter?)

Thanks!

like image 512
factotum Avatar asked Jul 25 '14 04:07

factotum


1 Answers

Declare a primary template and leave it unimplemented.

template<typename T>
struct foo;     // unimplemented primary template

Then provide a partial specialization that matches function types as the template argument.

template<typename Result, typename... Args>
struct foo<Result(Args...)>
{
    using args_t = std::tuple<Args...>;
};

You can access the nested type as

foo<decltype(bar)>::args_t

Live demo

like image 52
Praetorian Avatar answered Oct 04 '22 22:10

Praetorian