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

Tags:

C++

Templates