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

大城市里の小女人 提交于 2019-12-05 23:01:20

问题


It is continuation of this question. I am specifically interested if the partial specialization of a member class like this:

struct FooParent {
    template <class>
    struct Bar{ };
};

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

I know this can be done inside a namespace scope:

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

But I'm also specifically interested in in-class partial specialization at the level of derived class.

Both clang and gcc complains when encounter a former:

clang states that there is an explicit template specialization which obviously does not occur:

error: explicit specialization of 'Bar' in class scope

gcc is a little bit less verbose here and says that the specialization of the member template must be performed at a namespace scope which obviously is not a case for not derived class.

error: specialization of 'template struct FooParent::Bar' must appear at namespace scope

Is gcc right here in his error message?


回答1:


I'm trying to sum up what I said in the comments to the question, as requested by the OP.


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

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

In this case, what actually rule on it is where the primary template can be defined.
In the example, you are trying to declare (and contextually define, but it's first of all a declaration) a partial specialization in a derived class.

The short answer is: you cannot define the primary template in the derived class, so you cannot declare a partial specialization in that class as well.

If it was possible , the following would have been possible too:

struct FooParent {
    template <class>
    struct Bar;
};

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

Or this one if you prefer:

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

Unfortunately (?) they are not allowed and this would suffice to tell you that your attempt to specialize the class template is invalid as well.

Anyway, let's consider it a bit further.
The primary template is part of the member specification of Foo (see here for further details).
Thus, the question - where can I define such a template?, quickly becomes - where can I define any other member of the class?.
Again, the answer is - not in the scope of a derived class.


I'm pretty sure that a language-lawyer would give you more direct and straightforward explanation.
I'm also pretty sure that the same language-lawyer would curse me for having mentioned the wrong sections of the standard.
Anyway, I hope the few examples above can give you a base point from which to start.



来源:https://stackoverflow.com/questions/40685032/is-it-legal-to-perform-partial-in-class-specialization-of-a-member-template-clas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!