С++ 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.