1

This question seeks clarification on a section of the following documentation on partial template specialisation:

partial template specialization

My question pertains to the following text under the heading Members of partial initialization:

If a class template is a member of another class template, and it has partial specializations, these specializations are members of the enclosing class template. If the enclosing template is instantiated, the declarations of each member partial specialization is instantiated as well (the same way declarations, but not definitions, of all other members of a template are instantiated)

If the primary member template is explicitly (fully) specialized for a given (implicit) specialization of the enclosing class template, the partial specializations of the member template are ignored for this specialization of the enclosing class template.

If a partial specialization of the member template is explicitly specialized for a given (implicit) specialization of the enclosing class template, the primary member template and its other partial specializations are still considered for this specialization of the enclosing class template.

The example section demonstrating above mentions the following:

template<class T> struct A { // enclosing class template
  template<class T2>
  struct B {}; // primary member template
  template<class T2>
  struct B<T2*> {}; // partial specialization of member template
};

template<>
template<class T2>
struct A<short>::B {}; // full specialization of primary member template
                       // (will ignore the partial)

A<char>::B<int*> abcip; // uses partial specialization T2=int
A<short>::B<int*> absip; // uses full specialization of the primary (ignores partial)
A<char>::B<int> abci; // uses primary

I don't understand the distinction between the three cases above, which warrant a different treatment in each case, based on the text reproduced above.

Can anyone provide a simple explanation?

HTNW
  • 27,182
  • 1
  • 32
  • 60
user9196120
  • 381
  • 3
  • 9

1 Answers1

0

Since I am not sure that i got your question correctly, so please be indulgent. I assume that you want to know the difference and the reason for the behavior in your presented instantiations.

First you need to know how the compiler chooses which template specialization to use. There is a nice explanation here, but it mostly breaks down to: The compiler chooses always the template most restricted/specialized template specialization.

So now, lets look at the first instantiation you do there:
A<char>::B<int*> abcip;
Since there exists no full specialization for A<char>::B, we look into the general definition of A and find two matching template specializations for B<int*>.
B<T2> with T2=int* and B<T2*> with T2=int.
Since B<T2*> is the more restricted one, we choose this one.

Lets now look at the second instantiation:
A<short>::B<int*> absip;
Paragraph 2 of your quoted text now applies, since there exists a full specialisation of the primary member template A<short>::B. The partial specialization A<T>::B<T2*> will not be considered. This makes sense due to the fact that A<short>::B<T2> is more specialized than A<T>::B<T2*>. Things would change if we were to add the following to your code:

template<>
template<class T2>
struct A<short>::B<T2*> {};

Since this is even more specialized, it would be the chosen template for this instantiation.

The last instantiation simply chooses the primary member template A<T>::B<T2>, because this is the only matching type.

nnolte
  • 1,628
  • 11
  • 25