In 14.5.5.1 Matching of class template partial specializations, there is
If more than one matching specialization is found, the partial order rules (14.5.5.2) are used to determine
whether one of the specializations is more specialized than the others. If none of the specializations
is more specialized than all of the other matching specializations, then the use of the class template is
ambiguous and the program is ill-formed.
However, this would only apply to your first case where there are two specializations visible, and I am not sure yet if those two specializations are valid in themselves.
In your second case, however, before the second specialization is reached, the template-id Unique<3>
already exists, for which (thanks n.m., Matthieu M., James Kanze) the first specialization is already instantiated:
14.5.5 Class template partial specializations
A partial specialization shall be declared before the first use of a class template specialization that would make use of the partial specialization as the result of an implicit or
explicit instantiation in every translation unit in which such a use occurs; no diagnostic is required.
And in 14.5.5, Item 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 ]
So it seems that non-type arguments do not participate in specialization creation, if not used as a simple identifier (thus Range<(value > 2)>
would be wrong).
So it seems your code is not well-formed.
Not directly related but still interesting in this regard:
14.7.3 Explicit specialization
The placement of explicit specialization declarations for function templates, class templates, member functions
of class templates, static data members of class templates, member classes of class templates, member
class templates of class templates, member function templates of class templates, member functions of member
templates of class templates, member functions of member templates of non-template classes, member
function templates of member classes of class templates, etc., and the placement of partial specialization
declarations of class templates, member class templates of non-template classes, member class templates of
class templates, etc., can affect whether a program is well-formed according to the relative positioning of
the explicit specialization declarations and their points of instantiation in the translation unit as specified above and below. When writing a specialization, be careful about its location; or to make it compile will be
such a trial as to kindle its self-immolation.