在派生类

时间:2016-11-18 19:55:52

标签: c++ templates language-lawyer template-specialization partial-specialization

这是this问题的延续。如果成员类部分专业化如下,我特别感兴趣:

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

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

我知道这可以在命名空间范围内完成:

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

但我对派生类级别的课堂内部分专业化也特别感兴趣。

当遇到前任时,clang和gcc都会抱怨:

clang声明存在显式模板特化,显然不会发生:

  

错误:类范围中“Bar”的显式特化

gcc在这里稍微冗长一点,并说成员模板的特化必须在命名空间范围内执行,这显然不是非派生类的情况。

  

错误:'template struct FooParent :: Bar'的特化必须出现在命名空间范围

gcc是否在他的错误消息中?

1 个答案:

答案 0 :(得分:1)

我正在按照OP的要求,总结我在问题评论中所说的内容。

我猜[temp.class.spec]/5就足以回答这个问题了 特别是:

  

可以在任何可以定义相应主模板的命名空间范围内声明或重新声明类模板部分特化。

在这种情况下,实际上规则是可以定义主要模板的位置 在该示例中,您尝试声明(并在上下文中定义,但它首先是声明)派生类中的部分特化。

简短的回答是:您无法在派生类中定义主模板,因此您也无法在该类中声明部分特化。

如果可能的话,也可以采取以下措施:

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

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

如果你愿意,可以选择这个:

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

不幸的是(?)他们是不被允许的,这足以告诉你,你专门研究类模板的尝试也是无效的。

无论如何,让我们进一步考虑一下 主要模板是Foo成员规范的一部分(有关详细信息,请参阅here) 因此,问题 - 我在哪里可以定义这样的模板?,很快变成 - 我在哪里可以定义该类的任何其他成员?
同样,答案是 - 不在派生类的范围内

我很确定语言律师可以给你更直接,更直接的解释 我也很确定同一位语言律师会因为提到标准的错误部分而诅咒我 无论如何,我希望上面的几个例子可以为你提供一个基点,从中开始。