Is it legal to perform partial intraclassical specialization of a member template class in a derived class

This is a continuation of the this question. I'm particularly interested in the partial class specialization :

struct FooParent { template <class> struct Bar{ }; }; struct Foo: FooParent { template <class T> struct Bar<T*> {}; }; 

I know this can be done in the namespace area:

 template <class T> struct Foo::Bar<T*>{ }; 

But I'm also particularly interested in partial specialization in a class at the derived class level.

Both clang and gcc complain when they encounter the previous:

clang states that there is an explicit template specification that obviously does not arise:

error: explicit specialization "Bar" in the scope of the class

gcc is a little smaller here, and says that the specialization of the member template should be done in the namespace area, which obviously does not belong to the non-derived class.

error: specialization "template structure FooParent :: Bar" should be displayed in the namespace area

Is gcc right here in my error message?

+7
c ++ language-lawyer templates template-specialization partial-specialization
source share
1 answer

I am trying to summarize what I said in the comments on the question, at the request of the OP.


I think [temp.class.spec] / 5 is enough to answer the question.
In particular:

Partial specialization of the template template can be announced or updated in any area of ​​the namespace in which the corresponding primary template can be defined [...].

In this case, that is actually the rule on it where the primary pattern can be defined.
In this example, you are trying to declare (and contextually define, but primarily declare) a partial specialization in a derived class.

Short answer: you cannot define the main template in a derived class, therefore, you also cannot declare a partial specialization in this class.

If it were possible, the following would be possible:

 struct FooParent { template <class> struct Bar; }; struct Foo: FooParent { template <class T> struct FooParent::Bar<T*> {}; }; 

Or this if you prefer:

 struct Foo: FooParent { template <class T> struct Bar<T*> {}; }; 

Unfortunately (?) They are unacceptable, and it would be enough for you to say that your attempt to specialize the template template is also invalid.

In any case, consider a little more.
The main template is part of the Foo member specification (see here for more details).
So the question is - where can I define such a pattern ?, quickly becomes - where can I define any other member of the class ?.

Again, the answer is not in the area of ​​a derived class.


I am sure that a language attorney will give you a more direct and direct explanation.
I am also sure that the same language attorney curses me for mentioning the wrong sections of the standard.
Anyway, I hope that the few examples above can give you a base point from which to start.

+1
source share

All Articles