20

在 C++ (C++11) 标准的不同地方,声明是根据derived-declarator-type-list来描述的。我正在研究右值引用,在这种情况下使用这个术语是至关重要的(第 8.3.2 节):

在声明TD中,其中D具有以下形式之一
    & attribute-specifier-seq opt D1
    && attribute-specifier-seq opt D1并且声明T D1
中标识符的类型是“<em>derived-declarator-type-list T,”那么D的标识符的类型 是“<em>derived-declarator-type-list reference to T。”</p>

不幸的是,标准中从未定义“派生声明器类型”类别。(我查看了“派生”一词的所有用法,此外,这可能在此处此处得到证实。)

因为“ derived-declarator-type-list ”是斜体,我假设它指的是一个类别,而不是一个变量标签,例如T(因此,我不同意 Doug Gwyn 在我刚刚给出的第二个链接中的评估“我们可以已使用X而不是“派生声明符类型列表”)。

C++11 标准中对derived-declarator-type的定义是什么?

4

1 回答 1

16

它是在那里被定义的。这是一种将之前T遇到的任何东西带到下一个类型的方式,类似于:

<some stuff> T
<some stuff> reference to T

它只是T在类型中出现的任何内容T D1

例如,如果您有声明int& (*const * p)[30], Tis int, Dis& (*const * p)[30]D1is (*const * p)[30]。的类型T D1是“指向 30 int 数组的 const 指针的指针”。因此,根据您引用的规则,类型p是“指向 const 的指针,指向 30 引用 int 的数组的指针”。

当然,此声明随后被 §3.4.2/5 禁止:

不应有对引用的引用,没有引用数组,也没有指向引用的指针。

我认为它是派生声明类型列表的非正式术语来自 C 标准对派生类型的定义(类似于 C++ 中的复合类型):

可以从对象、函数和不完整类型构造任意数量的派生类型,如下所示:

  • 数组类型[...]
  • 结构类型[...]
  • 联合类型[...]
  • 函数类型[...]
  • 指针类型[...]

回应评论:您似乎对类型和声明符感到困惑。例如,如果int* p是声明符,那么类型p是“指向 int 的指针”。类型表示为这些类似英语的句子。

示例 1int *(&p)[30]

这是一个声明T D,其中(§8.3.1 指针):

  • T->int
  • D->*(&p)[3]

D具有以下形式:

* 属性说明符序列选择 cv 限定符序列选择 D1

D1在哪里(&p)[3]。这意味着具有“对数组 3 的引用”类型T D1的形式(您可以递归地解决这个问题,下一步使用 §8.3.4 数组等)。之前的所有内容都是derived-declarator-type-list。所以我们可以推断在我们的原始声明中具有类型“对 3 指针数组的引用”。魔法!int (&p)[3]intintpint

示例 2float (*(*(&e)[10])())[5]

这是一个声明T D,其中(§8.3.4 数组):

  • T->float
  • D->(*(*(&e)[10])())[5]

D形式为:

D1 [ 常量表达式选择 ] 属性说明符序列选择

D1在哪里(*(*(&e)[10])())。这意味着T D1的形式是float (*(*(&e)[10])())“引用 10 个指针的数组,指向 () 返回指向浮点的指针的函数”(您可以通过应用 §8.3/6 然后 §8.3.1 指针等来计算)。之前的所有float内容都是derived-declarator-type-list。所以我们可以推断p在我们的原始声明中具有类型“对 10 的数组的引用,指向 () 的函数的指针,返回指向 5 浮点数组的指针”。又是魔法!

于 2012-12-08T16:22:45.327 回答