4
votes

According to [temp.class.spec] 5/ (emphasis mine)

A class template partial specialization may be declared or redeclared in any namespace scope in which the corresponding primary template may be defined

This would suggest that partial specialization (just like in case of explicit specialization) have to appear in the namespace scope. This is actually confirmed by the example below the paragraph:

template<class T> struct A {
     struct C {
          template<class T2> struct B { };
     };
};
// partial specialization of A<T>::C::B<T2>
template<class T> template<class T2>
     struct A<T>::C::B<T2*> { };

//...
A<short>::C::B<int*> absip; // uses partial specialization

On the other hand C++ Standard Core Language Active Issues No 727 example suggests that in-class partial specialization is well formed:

struct A {
  template<class T> struct B;
  template <class T> struct B<T*> { }; // well-formed
  template <> struct B<int*> { }; // ill-formed
};

I'm sure core issues document is correct here, but cannot find appropriate reference to confirm that. Can you help me?

2
"A template can be declared within a class or class template; such a template is called a member template. ". Recall that partial specializations are themselfs templates.Johannes Schaub - litb
@JohannesSchaub-litb But why it doesn't apply to explicit specialization then? Aren't they templates as well?W.F.
you are figured it out. They are not templates. They are classes or functions or variables.Johannes Schaub - litb
@JohannesSchaub-litb this makes sense... If you find appropriate spec fragment I will accept the answerW.F.
@JohannesSchaub-litb classes and functions and variables can also be declared within a class template, no?T.C.

2 Answers

1
votes

The intent is that it is valid—see N4090:

Following a brief discussion of DR 17557 and DR 7278 in Issaquah 2014, and based on discussion on the core-reflector91011, it seems as if Core is converging on the following rules for member templates and their specializations: Partial specializations and explicit specializations can be first declared at either innermost-enclosing-class scope or enclosing namespace scope (recognizing that explicitly declaring specializations does not constitute adding members to a class and hence can be done after the closing brace).

7 http://www.open­std.org/jtc1/sc22/wg21/docs/cwg_toc.html#727
8 http://www.open­std.org/jtc1/sc22/wg21/docs/cwg_toc.html#1755
9 http://accu.org/cgi­bin/wg21/message?wg=core&msg=24366(24033, 24290, 24309, 24368)
10 http://accu.org/cgi­bin/wg21/message?wg=core&msg=24731(24731, 24732, 24736, 24738)
11 http://accu.org/cgi­bin/wg21/message?wg=core&msg=25168 (25168­-25179)

I filed a core issue, because I feel the current wording is not clear enough; the paragraph you quoted can be interpreted to disallow in-class partial specializations.

1
votes

The spec says at 14.5.2p1

A template can be declared within a class or class template; such a template is called a member template.

And at 14.5.5p2

Each class template partial specialization is a distinct template and definitions shall be provided for the members of a template partial specialization

Therefore, a class template partial specialization is a template, which is natural aswell because it still has parameters that are not fixed, therefore it denotes a "family of classes". And templates can be declared within a class or class template.