This is not a valid partial specialization (though the error could be better). The clause we are not inline with is the following:
[temp.class.spec]
8 Within the argument list of a class template partial
specialization, the following restrictions apply:
- The specialization shall be more specialized than the primary template.
"The specialization is not more specialized!?" I suppose you think. But that is indeed the case. The rules for determining which is "more specialized" are described in [temp.class.order]. The gist of it is that we are to consider two hypothetical function template overloads:
template <int I>
struct A { /* ... */ };
template<int I>
void foo(A<I>); //1
template<int I>
void foo(A<I + 5>); //2
We then perform overload resolution and partial ordering of the function templates. If #2 wins, it's more specialized and your declaration is legal. If it doesn't win, the declaration is invalid. Partial ordering is done by cooking up some arguments and doing template argument deduction of one template against another. So suppose we start with comparing the first to the second (I'll rename them for simplicity, but they are still overloads):
void foo1(A<0>); -> void foo2(A<I + 5>);
Does the argument deduction succeed here? It doesn't. I + 5
is a non-deduced context:
[temp.deduct.type]
The non-deduced contexts are:
5.3 - A non-type template argument or an array bound in which a
subexpression references a template parameter.
The I
references a template parameter, so I + 5
is a non-deduced context. Therefore template argument deduction fails in this direction.
Let's try the other direction. Again we cook up an argument
void foo2(A<1 + 5>); = void foo2(A<6>); -> void foo1(A<I>);
Deduction obviously succeeds here. So according to the rules of function template partial ordering, foo1
is more specialized than foo2
. This means that our primary is really more specialized than our "partial specialization", making the partial specialization ill-formed.
A<numeric_limits<int>::min()>
, ..,A<numeric_limits<int>::min() + 4>
. :) – Jarod42