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.
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.
Variadic generics are necessary for an Array that is generic in an arbitrary number of axes to be cleanly defined as a single class.
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.
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 , .
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;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With