Ответ 1
Он определяется прямо там и тогда. Это способ переносить все, что доходит до T
до следующего типа, похожее на:
<some stuff> T
<some stuff> reference to T
Это как раз то, что доходит до T
в типе T D1
.
Например, если у вас есть объявление int& (*const * p)[30]
, T
- int
, D
- & (*const * p)[30]
и D1
- (*const * p)[30]
. Тип T D1
- это "указатель на const указатель на массив из 30 int". Итак, согласно правилу, указанному вами, тип p
является "указателем на указатель const на массив из 30 ссылок на int".
Конечно, это выражение затем запрещено в §3.4.2/5:
Не должно быть ссылок на ссылки, нет массивов ссылок и ссылок на ссылки.
Я думаю, что неформальная терминология, являющаяся производным списком типов деклараторов, исходит из стандартного определения C производного типа (аналогичного составному типу в С++):
Любое число производных типов может быть построено из объекта, функции и неполными типами:
- Тип массива [...]
- Тип структуры [...]
- Тип объединения [...]
- Тип функции [...]
- Тип указателя [...]
В ответ на комментарии: похоже, вы путаетесь между типом и декларатором. Например, если int* p
является декларатором, то тип p
является "указателем на int". Тип выражается в виде этих англоязычных предложений.
Пример 1: int *(&p)[30]
Это объявление T D
где (§8.3.1 Указатели):
-
T
→int
-
D
→*(&p)[3]
D
имеет вид:
*
attribute-specifier-seq opt cv-qualifier-seq optD1
где D1
- (&p)[3]
. Это означает, что T D1
имеет вид int (&p)[3]
, который имеет тип "ссылка на массив из 3 int
" (вы рекурсивно выполняете это, следуя шагу, используя §8.3.4 Массивы и т.д.). Все, что находится перед int
, является списком типов производных-деклараторов. Таким образом, мы можем заключить, что p
в нашем исходном объявлении имеет тип "ссылка на массив из 3 указателей на int
". Магия!
Пример 2: float (*(*(&e)[10])())[5]
Это объявление T D
где (§8.3.4 Массивы):
-
T
→float
-
D
→(*(*(&e)[10])())[5]
D
имеет вид:
D1 [
константное выражение opt]
attribute-specifier-seq opt
где D1
- (*(*(&e)[10])())
. Это означает, что T D1
имеет вид float (*(*(&e)[10])())
, который имеет тип "ссылка на массив из 10 указателей на функцию(), возвращающую указатель на float" (который вы разрабатываете, применяя § 8.3/6, а затем §8.3.1 указатели и так далее). Все, что находится перед float
, является списком типов производных-деклараторов. Таким образом, мы можем заключить, что p
в нашем исходном объявлении имеет тип "ссылка на массив из 10 указателей на функцию(), возвращающую указатель на массив из 5 float". Магия снова!