Continuing my journey into the world of variadic templates, I encountered another problem.
Assuming the following template class:
template < typename T >
struct foo
{
//default implementation
};
it is possible to partially specialize it for variadic template instantiations like this:
template < template < typename ... > class T, typename ...Args >
struct foo< T< Args... > >
{
//specialized implementation
};
With this, foo< int >
will correspond to the default implementation and foo< std::tuple< int, char > >
to the specialized implementation.
However, things become more complicated when using several template parameters. For example, if we have the following template class
template < typename T, typename U >
struct bar {};
and we want to partially specialize it as we did for foo
, we cannot do
template < template < typename ... > class T, typename ...TArgs,
template < typename ... > class U, typename ...UArgs >
struct bar< T< TArgs... >, U< UArgs... > > {};
//This would correspond to the specialized version with
//T=std::tuple,
//TArgs=int,char
//U=std::tuple,
//UArgs=float
bar< std::tuple< int, char >, std::tuple< float > > b;
Indeed, if I am correct, we can only have one template parameter pack and it must be positioned at the end of the parameter list. I understand why this is mandatory in template declarations, but for certain partial template specialization (like the example above), this should not be an issue.
Is it possible to achieve partial template specialization with multiple template parameter packs?
Edit: Now I feel silly...the code I gave above compiles perfectly (at least with gcc 4.5). The compile error I had was not because of multiple parameter packs, but because of their use as member functions parameters. In the partial specialization of bar
, I tried to define a member function that takes both TArgs
and UArgs
parameters:
template < template < typename ... > class T, typename ...TArgs,
template < typename ... > class U, typename ...UArgs >
struct bar< T< TArgs... >, U< UArgs... > >
{
void method( TArgs... targs, UArgs... uargs ) //compile error here
{
}
};
On the member function declaration, gcc gives me the error
parameters packs must be at the end of the parameter list.
As far as I can tell, the compiler should be able to define the correct member function for a given template instantiation, e.g. bar< std::tuple< int, char >, std::tuple< float > >
should contain a member function void method( int, char, float )
. Am I doing something wrong? Or am I trying to do something that is not possible? If so, is there a good reason why this is not possible?