嵌套的 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
- 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,
- 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),
- 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
,名称 A
是 current instantiation
的名称,类似于 #3
。
#4
格式正确,因为它遵循 current instantiation
的第三个项目符号,因此对于 A::B
,其中 B
是当前实例化的名称。
但是,我无法理解为什么 #2
格式错误,换句话说,它需要关键字 typename
,根据第一个项目符号,不是nested class 被认为是当前实例化的名称?
坦率地说,我不知道如何理解第一颗子弹。至少,我觉得这句话含糊不清。这是否意味着只要在句子中列出的定义之一中,这些 injected-class-name
s(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, [...]
根据规则:
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
- 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,
- 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),
- 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
,名称 A
是 current instantiation
的名称,类似于 #3
。
#4
格式正确,因为它遵循 current instantiation
的第三个项目符号,因此对于 A::B
,其中 B
是当前实例化的名称。
但是,我无法理解为什么 #2
格式错误,换句话说,它需要关键字 typename
,根据第一个项目符号,不是nested class 被认为是当前实例化的名称?
坦率地说,我不知道如何理解第一颗子弹。至少,我觉得这句话含糊不清。这是否意味着只要在句子中列出的定义之一中,这些 injected-class-name
s(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, [...]