С++ 11 decltype (e) - это тип объекта с именем e
Я не спрашиваю decltype((x))
, я знаю, как это работает.
Согласно проекту N4687, § 10.1.7.2
4 For an expression e, the type denoted by decltype(e) is defined as follows:
...
(4.2) — otherwise, if e is an unparenthesized id-expression or an unparenthesized class
member access (8.2.5), decltype(e) is the type of the entity named by e. If
there is no such entity, or if e names a set of overloaded functions, the
program is ill-formed;
...
И пример
struct A { double x; };
const A* a = new A();
decltype(a->x) x3; // type is double
Мой вопрос,
a->x
const double
, но почему x3 является double
? где идет const
?
BTW, что означает decltype(e) is the type of the entity named by e
точно?
Ответы
Ответ 1
Стандарт кажется неоднозначным в этой области.
Сущность - это значение, объект, ссылка, функция, перечислитель, тип, член класса, бит-поле, шаблон, специализация шаблона, пространство имен или пакет параметров.
Выражение a->x
можно назвать именем x
элемента struct A
, имеющего тип double
. Это же выражение можно назвать именем объекта с типом const double
. Обе эти вещи являются сущностями. В нормативном тексте не делается абсолютно ясно, что предполагаемая интерпретация является первой, ее можно сделать только из примера.
Ответ 2
N4687 [dcl.type.simple] & para; 4.2... if e
- это безударное id-выражение или unparenthesized доступ к члену класса, decltype(e)
- это тип объекта с именем e
.
Доступ к члену класса является либо .
, либо ->
, в соответствии с [expr.ref].
[basic] & para; 3 Сущность - это значение, объект, ссылка, функция, перечислитель, тип, член класса, бит-поле, шаблон, специализация шаблона, пространство имен или пакет параметров.
& para; 4 Имя - это идентификатор, оператор-функция-id, литерал-оператор-идентификатор, идентификатор конверсии или идентификатор шаблона, который обозначает объект или метку.
& para; 5 Каждое имя, обозначающее объект, вводится декларацией.
Здесь есть двусмысленность: a->x
- и член класса, и объект (подобъект-член). Важно отметить, что decltype(e)
- это тип объекта , названного e
. Единственными видами объектов, которые могут быть с именем, являются те, которые вводятся объявлениями (& para; 5). Субобъект-член не имеет имени в этом смысле, поскольку он не объявлен. Это оставляет единственную альтернативу, что decltype(x->a)
должен быть типом члена класса (а не члена объекта).
Ответ 3
"Сущность", названная выражением доступа к члену класса, является членом класса, в данном случае A::x
.
Тип A::x
- double
.