Partial template specialization with multiple template parameter packages

Continuing my journey into the world of variable templates , I ran into another problem.

Assuming the following class of templates:

template < typename T > struct foo { //default implementation }; 

you can partially specialize it for modifications to template templates as follows:

 template < template < typename ... > class T, typename ...Args > struct foo< T< Args... > > { //specialized implementation }; 

In this case, foo< int > will correspond to the default implementation and foo< std::tuple< int, char > > for a specialized implementation.

However, when using several template parameters, everything becomes more complicated. For example, if we have the following class of templates

 template < typename T, typename U > struct bar {}; 

and we want to partially specialize it, as it was done 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 right, we can only have one package of template parameters, and it should be located at the end of the parameter list. I understand why this is necessary in template declarations, but for a certain partial specialization of a template (for example, the example above) this should not be a problem.

Is it possible to achieve partial specialization of templates with several packages of template parameters?




Edit : now I feel stupid ... the code I gave above compiles fine (at least with gcc 4.5). I had a compilation error not because of several packages of parameters, but because of their use as parameters of member functions. In a partial specialization of bar I tried to define a member function that accepts the TArgs and UArgs :

 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 { } }; 

The gcc member function declaration gives me an error

Parameter Packages

must be at the end of the parameter list.

As far as I can tell, the compiler should be able to determine the correct member function for a given instance of the template, for example. bar< std::tuple< int, char >, std::tuple< float > > must contain the void method( int, char, float ) member function void method( int, char, float ) . Am I doing something wrong? Or am I trying to do something that is impossible? If so, is there a good reason why this is not possible?

+15
c ++ c ++ 11 templates variadic-templates
Jan 16 2018-11-16T00:
source share
1 answer

Probably this answer will not immediately clear your question, but the following code compiled on ideone (gcc-4.5.1) when I tested.

 #include <cstdio> #include <tuple> template< class, class > struct S { S() { puts("primary"); } }; template< template< class... > class T, class...TArgs , template< class... > class U, class...UArgs > struct S< T< TArgs... >, U< UArgs... > > { S() { puts("specialized"); } }; int main() { S< int, int > p; // "primary" S< std::tuple< int, char >, std::tuple< float > > s; // "specialised" } 

I'm not sure if this code strictly matches, but as far as I read N3225 14.5.3, I could not find a statement that mentions this package of template parameters should be the last template parameter.

Edit:
I reread the N3225 and found the following statements:

8.3.5 / 4 If the parameter-declaration-sentence ends with an ellipsis or the parameter packet of the function (14.5.3), the number of arguments must be equal to or greater than the number of parameters that do not have a default argument and the parameter packets do not function.

14.8.2.5/10 [Note. A package of function parameters can only be executed at the end of the -definition-declarationlist (8.3.5). end note]

So, as you mentioned, the function parameter package should be the last parameter unfortunately.
A template function that is not a template of a class template is a normal function for this class when it is created (fully specialized). Therefore, I want the code in this question to be compiled logically, as a special case.

+6
Jan 16 '11 at 18:21
source share



All Articles