I have read What does template's implicit specialization mean? and its answers, but I am still not satisfied that I understand this part of Partial template specialization from cppreference.com:
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....
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
Questions:
The comments say that the line template<> template<classT2> struct A<short>::B {};
is a "full specialization of primary member template". The primary member template is identified in the comments as the structure B
. How can the line be a specialization of B
when it is A
that is being specialized by the substitution of short
for class T
?
How can the line be a "full" specialization of B
when the template parameter T2
is left unspecified?
The comments and the accompanying text indicate that "explicit specialization" and "full specialization" are synonymous terms. If the line of code quoted above is the explicit specialization of B
, where is the implicit specialization of A
?
A member of a class template can be explicitly specialized even if it is not a template:
template<int I>
struct X {
int f() {return I;}
void g() {}
};
template<>
int X<0>::f() {return -1;}
This is equivalent to specializing the whole class template but with other members duplicated from the relevant primary template or partial specialization:
template<>
struct X<0> {
int f() {return -1;}
void g() {}
};
(Recall that such a spelled-out specialization is under no obligation to declare g
at all or as a function.) Since you don’t actually write this, it’s still considered to be an implicit instantiation of X
as a whole with the given alteration.
This is why your specialization of A<T>::B
provides the template argument for A
and not for B
; it is replacing the template A<T>::B
with another template (that happens to have the same template parameter list). I would say the word “primary” is misleading here: it is the whole template that is replaced, which is why the partial specialization is ignored for A<short>
thereafter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With