嵌套的 class 名称在封闭的 class 模板中使用时是否被视为当前实例化

Is a nested class name be considered as a current instantiation when it is used in a enclosing class template

根据规则:
temp.res#3

When a qualified-id is intended to refer to a type that is not a member of the current instantiation ([temp.dep.type]) and its nested-name-specifier refers to a dependent type, it shall be prefixed by the keyword typename, forming a typename-specifier. If the qualified-id in a typename-specifier does not denote a type or a class template, the program is ill-formed.

这意味着,当当前实例化的成员用作类型说明符时,它没有必要以关键字 typename.

作为前缀

请考虑以下代码:

#include <iostream>
template<class T>
struct A{
    struct B{
        struct C{
           A::B* p; //#5
        };
      B::C c;  //#3
      A::B::C d; //#4
    };
    A::B a;  //#1
    /*B::C b;*/  //#2
};
int main(){

}

当前实例化的定义是: temp.dep.type#1

A name refers to the current instantiation if it is

  1. in the definition of a class template, a nested class of a class template, a member of a class template, or a member of a nested class of a class template, the injected-class-name of the class template or nested class,
  2. in the definition of a primary class template or a member of a primary class template, the name of the class template followed by the template argument list of the primary template (as described below) enclosed in <> (or an equivalent template alias specialization),
  3. in the definition of a nested class of a class template, the name of the nested class referenced as a member of the current instantiation, or

由于 current instantiation 的第一个项目符号,#1 处的声明格式正确。也就是说,在 #1,名称 Acurrent instantiation 的名称,类似于 #3

#4 格式正确,因为它遵循 current instantiation 的第三个项目符号,因此对于 A::B,其中 B 是当前实例化的名称。

但是,我无法理解为什么 #2 格式错误,换句话说,它需要关键字 typename,根据第一个项目符号,不是nested class 被认为是当前实例化的名称?

坦率地说,我不知道如何理解第一颗子弹。至少,我觉得这句话含糊不清。这是否意味着只要在句子中列出的定义之一中,这些 injected-class-names(primary class name or nested class name) 都被视为当前实例化的名称? #2似乎不​​支持这种解释。

我可以从这个例子中推断出,嵌套的class中的enclosing class name可以被认为是当前实例化的名称,而不是相反。如果这样理解句子,就可以理解为什么#5处的代码是合式的了。

那么,如何正确读出第一个项目符号呢?你同意这句话含糊吗?

Is a nested class name be considered as a current instantiation when it is used in a enclosing class template?

没有

然而,与标准的许多其他段落一样,第 [temp.dep.type]/1.1 段确实很冗长:

A name refers to the current instantiation if it is

  • (1.1) in the definition of a class template, a nested class of a class template, a member of a class template, or a member of a nested class of a class template, the injected-class-name of the class template or nested class, [...]

我们可能需要将其分解为不同的情况,以了解它不适用于 class 模板定义中的嵌套-class-名称,其中,依次,嵌套的class定义为:

A name refers to the current instantiation if it is,

  • in the definition of a class template, the injected-class-name of the class template ["or nested class" does not apply for this case]
  • in the definition of a nested class of a class template, the injected-class-name of the class template or [the] nested class
  • in the definition of a member of a class template, the injected-class-name of the class template ["or nested class" does not apply for this case]
  • in the definition of a member of a nested class of a class template, the injected-class-name of the class template or [the] nested class

强调的联系”如果它在定义的X中( of a Y), the X 的注入-class-名称 (or [the] Y)"。特别注意,当定义是 class 模板时(当 X 是 class 模板时),没有 "a 嵌套 class" 到回头参考后面的部分,在描述“injected-class-name of the ...”时。

相反,无法将 [temp.dep.type]/1.1 解释为

" in the definition of a class template, the injected-class-name of the class template or any nested class of the class template "

因此,在你的例子中,#2,我们在中定义了一个class模板(即A),意思是只有class模板本身的名称,即A,指的是当前实例化


Do you agree the sentence is vague?

鉴于上述情况,我不会说它是模糊的(因为这意味着一些 歧义 ,我看不到),但可能不必要地复杂。如果将 [temp.dep.type]/1.1 分成两个单独的段落,可以说会更清楚:

A name refers to the current instantiation if it is

  • (1.1a) in the definition of a class template, or a member of a class template, the injected-class-name of the class template,
  • (1.1b) in the definition of a nested class of a class template, or a member of a nested class of a class template, the injected-class-name of the class template or nested class, [...]