模板模板成员的消歧模板关键字:何时完全?

时间:2011-06-23 15:29:12

标签: c++ templates

这里给出了关于模板消歧器的问题:

template disambiguator

在答案中我们可以读到:

ISO C ++ 03 14.2/4

  

当成员模板专业化的名称出现之后。或 - >在postfix-expression中,或者在qualified-id中的nested-name-specifier之后,postfix-expression或qualified-id显式依赖于template-parameter(14.6.2),成员模板名称必须以关键字模板。否则,假定该名称命名非模板。

现在我来了一个我不太明白的例子:

template <class T>
class Base {
  public:


  template <int v>
    static int baseGet() {return v;}

  class InnerA {
    public:

    template <int v>
      static int aget() {return v;}

  };

  class InnerB {
    public:
      typedef Base BaseType;
      typedef BaseType::InnerA OtherType;

      template <int v>
        static int baseGet() {return BaseType::baseGet<v>();} //(A)

      template <int v>
        static int aget() {return OtherType::aget<v>();} //(B)
  };
};

显然无法编译。您需要{B}中的template OtherType::template aget<v>();template。 但是,g ++(4.4.3)和clang ++(2.9)都没有抱怨行(A)中缺少BaseType。为什么? T取决于类型{{1}},不是吗?这些编译器是否与标准有所不同,或者我是否误解了标准中的某些内容?

3 个答案:

答案 0 :(得分:8)

它们实现了C ++ 0x规范,其中Base当前实例化。在这种情况下,C ++ 0x允许省略template关键字。由于BaseTypeBase的typedef,因此当您说BaseType时,它也会命名当前的实例化。

引用规范,因为您似乎对spec refs感兴趣

  

名称是当前实例化的成员,如果它是[...]

     
      
  • 一个qualified-id,其中嵌套名称指定者引用当前实例化,并且当查找时,指的是当前实例化的至少一个成员或非依赖基础一类。
  •   

  

名称是指当前实例化,如果它是[...]

     
      
  • 在类模板的[strong]嵌套类的定义中,[...],注入类名(第9条)类模板或嵌套类
  •   

和(你引用的修改后的14.2 / 4)

  

[...]或qualified-id中的nested-name-specifier引用依赖类型,但名称不是当前实例化的成员(14.6.2.1),成员模板名称必须以前缀为前缀通过关键字模板。 [...]


注意:在C ++ 03中,您的代码格式错误,因为BaseTypeOtherType都是依赖的。规范说:

  

如果是[...]

,则类型是依赖的      
      
  • 模板参数
  •   
  • 带有嵌套名称说明符的qualified-id,其中包含一个命名依赖类型的类名
  •   
  • 模板ID,其中模板名称是模板参数或任何模板参数是依赖类型
  •   

(请注意,Base相当于Base<T>BaseBaseType::InnerA是依赖类型的基础。

请注意,您的报价中的“明确取决于”是一个预先标准的术语,并且最近被淘汰了(我相信它是在1996年12月)。它基本上意味着(在此上下文中)限定符依赖的限定ID或a->x依赖的类成员访问(a.x / a)。从草案中删除“明确依赖”之后,它仍然潜伏在某些地方,甚至C ++ 0x仍然在14.6.2p2的注释中引用“明确依赖”:

  

基类名称B<T>,类型名称T::A,名称B<T>::ipb->j 明确依赖对template-parameter。

答案 1 :(得分:1)

因为OtherType嵌套依赖名称,而BaseType不是嵌套类型。

您需要将template用于嵌套依赖类型。

这里的关键词是:

  • 依赖类型
  • 嵌套类型

如果类型都是,那么您必须使用模板

  • OtherType是依赖类型(取决于T)以及嵌套类型
  • BaseType只是依赖类型(取决于T)。它不是嵌套类型。

答案 2 :(得分:0)

BaseType确实取决于类型T - 但InnerB也是如此。实际上,从BaseType<T>内的任何代码的角度来看,它都不依赖于T