在C ++(C ++ 11)标准的不同位置,声明是根据 derived-declarator-type-list 来描述的。我正在研究右值参考,在这种情况下使用这个术语是至关重要的(§8.3.2):
在声明中 T D ,其中 D 具有任何一种形式
&安培; attribute-specifier-seq opt D1
&安培;&安培; attribute-specifier-seq opt D1
以及声明 T D1 中的标识符类型是 “ derived-declarator-type-list T ,”然后是 D 标识符的类型 是“ derived-declarator-type-list 对 T 的引用。”
不幸的是,类别“ derived-declarator-type ”从未在标准中定义。 (我查看了“衍生”一词的每次使用,此外,这可能已经确认here和here。)
因为“ derived-declarator-type-list ”是斜体,我认为它指的是一个类别,而不是一个变量标签,例如 T
(因此,我不同意Doug Gwyn在我刚刚给出的第二个链接中的评估“我们可以使用 X
而不是' derived-declarator-type-list < / em>'“)。
C ++ 11标准中 derived-declarator-type 的定义是什么?
答案 0 :(得分:12)
它正在那里被定义。这是将T
之前的任何内容传递到下一个类型的方式,类似于:
<some stuff> T
<some stuff> reference to T
这只是T
类型T D1
之前的任何内容。
例如,如果您有声明int& (*const * p)[30]
,T
为int
,则D
为& (*const * p)[30]
且D1
为{{1} }}。 (*const * p)[30]
的类型是“指向指向30 int数组的const指针”。因此,根据您引用的规则,T D1
的类型是“指向指向30引用数组的数组的const指针”。
当然,§3.4.2/ 5不允许这个声明:
不应引用引用,不引用引用数组,也不引用引用指针。
我认为它是派生的声明符类型列表的非正式术语来自C标准对派生类型的定义(类似于C ++中的复合类型):
可以从对象,函数和构造任意数量的派生类型 不完整的类型,如下:
- 数组类型 [...]
- 结构类型 [...]
- 联合类型 [...]
- 功能类型 [...]
- 指针类型 [...]
回应评论:似乎你在类型和声明者之间感到困惑。例如,如果p
是声明符,则int* p
的类型是“指向int的指针”。类型表示为这些类似英语的句子。
示例1 :p
这是一个声明int *(&p)[30]
,其中(§8.3.1指针):
T D
- &gt; T
int
- &gt; D
*(&p)[3]
的格式为:
D
attribute-specifier-seq opt cv-qualifier-seq opt {{ 1}}
其中*
为D1
。这意味着D1
的格式为(&p)[3]
,其类型为“引用数组3 T D1
”(您可以递归地执行此操作,下一步使用§8.3.4数组等) 。 int (&p)[3]
之前的所有内容都是 derived-declarator-type-list 。因此,我们可以推断出我们原始声明中的int
类型为“引用指向int
的3指针数组”。魔术!
示例2 :p
这是一个声明int
,其中(§8.3.4数组):
float (*(*(&e)[10])())[5]
- &gt; T D
T
- &gt; float
D
具有以下形式:
(*(*(&e)[10])())[5]
常量表达式 optD
attribute-specifier-seq opt
其中D1 [
为]
。这意味着D1
的格式为(*(*(&e)[10])())
,其类型为“引用指向函数的10指针的数组”(返回指向float的指针)(您可以通过应用§8.3/ 6然后§来解决) 8.3.1指针等)。 T D1
之前的所有内容都是 derived-declarator-type-list 。因此,我们可以推断出我们原始声明中的float (*(*(&e)[10])())
类型为“引用指向函数的10指针的数组()返回指向5浮点数组的指针”。再次魔术!