GCC is right, this is explicitly forbidden by C++11 [temp.class.spec] §8:
8 Within the argument list of a class template partial specialization, the following restrictions apply:
A partially specialized non-type argument expression shall not involve a template parameter of the
partial specialization except when the argument expression is a simple identifier. [ Example:
template <int I, int J> struct A {};
template <int I> struct A<I+5, I*2> {}; // error
template <int I, int J> struct B {};
template <int I> struct B<I, I> {}; // OK
—end example ]
The type of a template parameter corresponding to a specialized non-type argument shall not be
dependent on a parameter of the specialization. [ Example:
template <class T, T t> struct C {};
template <class T> struct C<T, 1>; // error
template< int X, int (*array_ptr)[X] > class A {};
int array[5];
template< int X > class A<X,&array> { }; // error
—end example ]
...
I believe point 2 is the most relevant one here.
Regarding the question of "how to solve this issue." In the form the question stands now, there is no workaround, I am afraid.
As for the original vesion with making integer sequences, I believe that you could make it work with using uintmax_t
for the type of the non-type template parameter, and only convert it to intT
in the final definition.