Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variadic variadic template templates

Tags:

I'm currently struggling with the following code, the intent of which is to implement variadic variadic template templates:

template
<
  template <typename... HeadArgs> class Head,
  template <typename... TailArgs> class...
>
struct join<Head<typename HeadArgs...>, Head<typename TailArgs...>...>
{
  typedef Head<typename HeadArgs..., typename TailArgs......> result;
};

Ideally, I'd be able to use this template metafunction to achieve the following:

template <typename...> struct obj1 {};
template <typename...> struct obj2 {};

typedef join
<
  obj1<int, int, double>, 
  obj1<double, char>,
  obj1<char*, int, double, const char*>
>::result new_obj1;

typedef join
<
  obj2<int, int, double>, 
  obj2<double, char>,
  obj2<char*, int, double, const char*>
>::result new_obj2;

/* This should result in an error, because there are 
   different encapsulating objects
typedef join
<
  obj1<int, int, double>, 
  obj1<double, char>,
  obj2<char*, int, double, const char*>
>::result new_obj;
*/

The output of the above would hopefully create new_obj1 and new_obj2 in the form template<int, int, double, double, char, char*, int, double, const char*> struct new_obj[1|2] {};

I'm using gcc 4.6.2 on Windows, which outputs an "expected parameter pack before '...'" for the expansion of "Head<typename TailArgs...>...".

This error is reproducable with gcc 4.5.1.

like image 412
kmore Avatar asked Mar 12 '12 06:03

kmore


People also ask

What is a variadic template C++?

Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration. However, variadic templates help to overcome this issue.

What is variadic generic?

Variadic generics are necessary for an Array that is generic in an arbitrary number of axes to be cleanly defined as a single class.

What is a parameter pack in C++?

Parameter packs (C++11) A parameter pack can be a type of parameter for templates. Unlike previous parameters, which can only bind to a single argument, a parameter pack can pack multiple parameters into a single parameter by placing an ellipsis to the left of the parameter name.

How do you expand a parameter pack?

Parameter packs can only be expanded in a strictly-defined list of contexts, and operator , is not one of them. In other words, it's not possible to use pack expansion to generate an expression consisting of a series of subexpressions delimited by operator , .


1 Answers

Try something like this:

template <typename...> struct join;

template <template <typename...> class Tpl,
          typename ...Args1,
          typename ...Args2>
struct join<Tpl<Args1...>, Tpl<Args2...>>
{
    typedef Tpl<Args1..., Args2...> type;
};

template <template <typename...> class Tpl,
          typename ...Args1,
          typename ...Args2,
          typename ...Tail>
struct join<Tpl<Args1...>, Tpl<Args2...>, Tail...>
{
     typedef typename join<Tpl<Args1..., Args2...>, Tail...>::type type;
};
like image 83
Kerrek SB Avatar answered Oct 01 '22 14:10

Kerrek SB