Let's say we have the following:
template<typename T1, typename T2>
class A {}
template<typename T1, typename T2>
class A<T1*, T2*> {}
template<typename T>
class A<T, T> {}
Now, I know that we need to select the most specialized class, but for A<double*, double*>, there is a ambiguity error for both specializations and my teacher told that they are having the same specialization level. But at the first look, I would have said A<T, T> is more specialized. How exactly did we come to this conclusion? Or how can we say if 2 different specializations are at same level or not?
First, regarding terminology: Each of these definitions are not definitions for classes. The first definition defines a primary class template. The other definitions define partial specializations of that primary template.
It is not possible to categorize partial specializations by "levels" of specialization. The actual rules are rather complicated and a reference can be found e.g. here.
But roughly, you can consider a partial specialization more specialized than another, if the latter would accept all template argument lists that the former would accept, but not the other way around.
In your case the first specialization accepts A<int*, long*>
, but the second one doesn't, and the second one accepts A<int, int>
, but the first one doesn't. So informally, we can see that neither is more specialized than the other.
The primary template is not more specialized than the partial specializations either, so A<double*, double*>
which would be accepted by all three without one of them being more specialized than all the others, is ambiguous and causes the program to be ill-formed.