c++11 decltype(e) is the type of the entity named by e

464 Views Asked by At


I am not asking decltype((x)), I know how it works.

According to the draft 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;
        ...

And example

struct A { double x; };
const A* a = new A();
decltype(a->x) x3; // type is double

My question is,
a->x is const double, but why does x3 is double? where does the const go?
BTW, what is decltype(e) is the type of the entity named by e meaning exactly?

3

There are 3 best solutions below

0
On

N4687 [dcl.type.simple] ¶4.2 ...if e is an unparenthesized id-expression or an unparenthesized class member access, decltype(e) is the type of the entity named by e.

A class member access is either . or ->, according to [expr.ref].

[basic] ¶3 An entity is a value, object, reference, function, enumerator, type, class member, bit-field, template, template specialization, namespace, or parameter pack.

¶4 A name is a use of an identifier, operator-function-id, literal-operator-id, conversionfunction-id, or template-id that denotes an entity or label.

¶5 Every name that denotes an entity is introduced by a declaration.

There is an ambiguity here: a->x is both a class member and an object (a member subobject). The important thing to note is that decltype(e) is the type of the entity named by e. The only kinds of entities that can be named are those that are introduced by declarations (¶5). A member subobject does not have a name in this sense, as it is not declared. That leaves the only other alternative that decltype(x->a) must be the type of the class member (not the object member).

3
On

The "entity" named by a class member access expression is that class member, in this case, A::x.

The type of A::x is double.

8
On

The standard seems ambiguous im this area.

An entity is a value, object, reference, function, enumerator, type, class member, bit-field, template, template specialization, namespace, or parameter pack.

The expression a->x can be said to name a member x of struct A, which has type double. The same expression can also be said to name an object which has type const double. Both of these things are entities. The normative text doesn't make it absolutely clear that the intended interpretation is the first one, it can only be inferred from the example.