How to determine which template will be used
Only primary templates (so no specializations) are taken into account to select more specialized overloads.
Once selection is done with primary template, we use the specialization if any.
Now, template<> void a<>(int*);
can only be specialization of template<typename T> void a(T)
(the other version has not been seen).
and template<> void b<>(int*);
is specialization of template<typename T> void b(T*)
(it is the more specialized matching overloads).
Notice that you might select specialization of b
by providing template instead of letting compiler deduce:
template<> void b<>(int*)
->template<typename T> void b(T*) with T=int
template<> void b<int>(int*)
->template<typename T> void b(T*) with T=int
template<> void b<int*>(int*)
->template<typename T> void b(T) with T=int*
so for:
int i;
a(&i); // a<T*> with T=int*, no specialization for a<U*> (U=int) exist -> generic template called
b(&i); // b<T*> with T=int*, specialization for b<U*> (U=int) exists -> specialization called
Due to the difference of the declaration order, the specialization belongs to different primary template.
For the 1st case, the specialization belongs to a(T)
. For the 2nd case, the specialization belongs to b(T*)
. During overload resolution between primary templates, the version taking T*
is always selected; then in the 1st case, the specialization won't be considered because it's not the specialization of a(T*
). But it's selected in the 2nd case because b(T*)
has the specialization.
i.e.
For the 1st case
overloading
- a(T)
- specialization --> a(int*)
- a(T*) // selected in overload resolution
For the 2nd case
overloading
- b(T)
- b(T*) // selected in overload resolution
- specialization --> b(int*) // then the specialization is selected