title: C++11: Calculating variadic function parameter types
body: <p>Let's say you want to write a function which gets passed an opaque handle to a function of unknown type (say, the name of a struct containing a function with an agreed-upon name), and forwards arguments to that function.</p>
  
  <p>In the non-variadic case, considering single-parameter functions for simplicity, there's two ways to do this: you can let the forwarding function take an argument of arbitrary type, and attempt to call the forwardee function with it, and the compiler will complain during template expansion if it turns out to be incompatible; or you can use decltype and assorted other mechanisms to figure out what type of parameter the forwardee function expects, and explicitly require an argument of that type. I don't know if there's any accepted terminology for these, so I'm going to call them "pass through" and "up front".</p>
  
  <p>The pass through method generalizes straightforwardly to functions with an arbitrary number of parameters, but the up front method doesn't.</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  template&lt;typename T, typename Arg&gt;
  void pass_through_1(Arg arg)
  {
      T::f(arg);
  }
  
  template&lt;typename T&gt; struct arg_of_1;
  
  template&lt;typename Ret, typename Arg&gt;
  struct arg_of_1&lt;Ret (Arg)&gt;
  {
      typedef Arg type;
  };
  
  template&lt;typename T&gt;
  void up_front_1(typename arg_of_1&lt;decltype(T::f)&gt;::type arg)
  {
      T::f(arg);
  }
  
  template&lt;typename T, typename... Args&gt;
  void pass_through_var(Args... args)
  {
      T::f(args...);
  }
  
  template&lt;typename T&gt; struct args_of_var;
  
  template&lt;typename...&gt; struct type_list;
  
  template&lt;typename Ret, typename... Args&gt;
  struct args_of_var&lt;Ret (Args...)&gt;
  {
      // typedef Args... type; // can't do this
      typedef type_list&lt;Args...&gt; type;
  };
  
  // template&lt;typename T&gt;
  // void up_front_var(typename args_of_var&lt;decltype(T::f)&gt;::type... args) // can't do this
  // {
  //     T::f(args...);
  // }
  
  struct test  
  { 
      static void f(int x) { std::cout &lt;&lt; x*9 &lt;&lt; std::endl; }
  };
  
  int main(int, char**)
  {
      pass_through_1&lt;test&gt;(7);
      up_front_1&lt;test&gt;(8);
      pass_through_var&lt;test&gt;(9);
      // up_front_var&lt;test&gt;(10);
      return 0;
  }
  </code></pre>
  
  <p>The problem is that parameter packs aren't allowed to be free-standing, only as template arguments, and if you wrap them in an enclosing template, there's no way to unwrap-and-unpack them in place, only by pattern matching.</p>
  
  <p>"Up front" has some advantages like better self-documentation, and better support for type inference (up_front&lt;T&gt; can itself be decltyped). Is there any way to make it work in the variadic case? (You could of course use std::tuple, but that's rather unsatisfying.)</p>