23

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.

8
  • 2
    The argument name inside the template specification of the template template argument is optional and entirely cosmetic; it's not actually available as a real parameter. Commented Mar 12, 2012 at 6:33
  • @KerrekSB is there any way to get the parameters of a template template parameter? Commented Mar 12, 2012 at 6:43
  • I edited my post; I was missing the variadic case. In answer to your question: Yes, by supplying an explicit template parameter (pack) and matching. Commented Mar 12, 2012 at 6:53
  • 3
    @kmore No, because once you provide parameters to a template, it's no longer a template. template_name< parameters > is a class and will match a plain class or typename template parameter. Commented Mar 12, 2012 at 6:54
  • Indeed. You should notice that join isn't actually matching templates, but types. So the templates are just a detail of the specialization, not a defining characteristic of join. Commented Mar 12, 2012 at 6:59

1 Answer 1

25

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;
};
Sign up to request clarification or add additional context in comments.

1 Comment

That's a perfect solution when combining the parameters of two objects. However, I'm looking to combine the parameters of a variable number of objects. I tried modifying your answer, but there's still an error with the expansion pack. EDIT: you beat me to it, thank you!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.