4

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?

SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
W.F.
  • 13,888
  • 2
  • 34
  • 81
  • 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 Nov 17 '16 at 14:03
  • @JohannesSchaub-litb But why it doesn't apply to explicit specialization then? Aren't they templates as well? – W.F. Nov 17 '16 at 14:05
  • 1
    you are figured it out. They are not templates. They are classes or functions or variables. – Johannes Schaub - litb Nov 17 '16 at 14:06
  • @JohannesSchaub-litb this makes sense... If you find appropriate spec fragment I will accept the answer – W.F. Nov 17 '16 at 14:08
  • 1
    @JohannesSchaub-litb classes and functions and variables can also be declared within a class template, no? – T.C. Nov 18 '16 at 03:29
  • @T.C. however as far as I know, there is an explicit rule that explicit specializations are forbidden within a class scope. The rule W.F quoted just allows declaring a partial spec without first having declared it within the class. It does not forbid something allowed elsewhere. – Johannes Schaub - litb Nov 18 '16 at 07:48
  • I think (direct or not) answer to my question can be found in [temp.class.spec.mfunc] /2 [link](http://eel.is/c++draft/temp.class.spec.mfunc#2) – W.F. Nov 18 '16 at 12:12

2 Answers2

1

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.

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • Did you mean to answer [this](http://stackoverflow.com/questions/40685032/is-it-legal-to-perform-partial-in-class-specialization-of-a-member-template-clas) question? So as the specialization of the kind `template Foo::Bar` is well formed the in-class specialization of Bar in derived class should be also valid? – W.F. Nov 19 '16 at 11:51
  • 1
    @W.F. No, I don't think I meant to answer that question. – Columbo Nov 19 '16 at 11:52
  • Oh sorry for confusion... need to inspect it deeper – W.F. Nov 19 '16 at 11:53
  • Not sure about the first sentence of your answer, but cited text definitely answers my question! Thank you very much for that! – W.F. Nov 19 '16 at 12:07
  • 1
    @W.F. What are you unsure about? The wording is either underspecified, because [temp.class.spec]/5 only gives a sufficient condition (but not a necessary) one, or defective, because the condition expressed is simply wrong. – Columbo Nov 19 '16 at 12:09
  • Ohhhh gosh I really need to talk more with native English speakers... Now I got your point! Thanks once again! – W.F. Nov 19 '16 at 12:12
  • It is not defective or underspecified, see my comment. – Johannes Schaub - litb Nov 19 '16 at 14:29
  • @JohannesSchaub-litb I don't think your reasoning is sufficient, and I think you would agree in that we would benefit from clearer wording. :-) – Columbo Nov 19 '16 at 14:33
  • @Columbo why is the reasoning not sufficient, though? – Johannes Schaub - litb Nov 19 '16 at 14:36
  • @JohannesSchaub-litb Because special rules apply to special constructs in the language. The paragraph quoted by the OP appears (at least to a significant portion of readers) to override the general rule that you quoted. – Columbo Nov 19 '16 at 14:37
  • @Columbo so here is another "may be" rule: "The names of the template parameters used in the definition of the member may be different from the template parameter names used in the class template definition.". That however does not mean that you cannot use the same names, it just allows using different names. Same in the quote by the OP, just a different scenario. – Johannes Schaub - litb Nov 19 '16 at 14:39
  • What they say, however, "(recognizing that explicitly declaring specializations does not constitute adding members to a class and hence can be done after the closing brace)." is not correct. That's even reinforced by 14.7.1p1's saying about "However, for the purpose of determining whether an instantiated redeclaration of a member is valid according to [class.mem], a declaration that corresponds to a definition in the template is considered to be a definition." and the accompanying note that talks about partial specializations. Compare with 9.2p2. – Johannes Schaub - litb Nov 19 '16 at 14:46
  • To conclude: I think that the "partial specialization is a member" is defective. But I don't think that this means that other parts of the spec are defective aswell. As far as OP's question is concerned, the spec is very clear there. As far as "partial specialization is a member" is concerned: If you declare a partial specialization inside of the class body, you declare a member. If you do so outside, you don't declare a member. That is the only thing that strikes me as illogical and needs fixing. – Johannes Schaub - litb Nov 19 '16 at 14:49
  • What the defective (other rule) means, I think, is: It declares a member, but it doesn't introduce a member name. Therefore, the sentence "and each such member-declaration shall either declare at least one member name of the class or declare at least one unnamed bit-field."should say "and each such member-declaration shall either declare at least one member name of the class or declare at least one unnamed bit-field or partial or explicit specialization". – Johannes Schaub - litb Nov 19 '16 at 14:52
  • @JohannesSchaub-litb To your first comment: as Richard Smith points out in your std-discussion thread, that statement should be talking about member *names*. I don't think that specializations shouldn't be members, but that we should carefully distinguish between members and member names. If you first declare a partial specialization outside, you do add a member, but not a new member *name*, which is why that works fine. Your third comment is on point, that quote is defective indeed. – Columbo Nov 19 '16 at 16:37
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/128537/discussion-between-columbo-and-johannes-schaub-litb). – Columbo Nov 19 '16 at 16:40
1

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.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • One thing bothers me in this definition - you can specialize template but you cannot specialize specialized template even though it is a template... – W.F. Nov 19 '16 at 15:22
  • @W.F. I think that the matter is a bit subtle: "A primary class template declaration is one in which the class template name is an identifier. A template declaration in which the class template name is a simple-template-id is a partial specialization of the class template named in the simple-template-id.". Therefore, both the primary template and any partial specialization are declarations of the same "class template". Just that one is "primary" and the other are "partial specialization". And then the two are separate templates again. – Johannes Schaub - litb Nov 19 '16 at 17:21
  • 1
    So, I think sometimes when we say we can "specialize a template", one talks about the "template" in the sense of the template-name, without any argument. And at other times when one talks about "class template", one talks about the specific definition of a class template: either the primary, or one of the partial specializations. – Johannes Schaub - litb Nov 19 '16 at 17:24
  • Since that doesn't seem to make much sense, I think another way to interpret "A template declaration in which the class template name is a simple-template-id is a partial specialization of the class template named in the simple-template-id." is to read it as "class template named *by* the simple-template-id". Recall that simple-template-id would look like "Foo" and that a class template conceptually is a family of classes. In this view, the class template that is specialized is not "Foo", but "Foo". – Johannes Schaub - litb Nov 19 '16 at 17:32
  • Very nice explanation! Thank you - I feel I learn very much from your answer/comments... Unfortunately I don't feel I'm in position to judge which answer is better as they are both valuable to me. I'll wait for you to settle some consensus in the matter... – W.F. Nov 19 '16 at 17:33