Search code examples
c++pointersreferencelanguage-lawyerdecltype

c++ why decltype(*pointer) yields a reference?


I wanted to know why, when I use decltype (* pointer), it defines the type of the variable as a reference. For example:

int i = 42, * p = & i;
decltype (* p) c = i;

Now c is a reference (linked to i). Why is it a reference and not an integer? I'm reading the book Cpp Primer 5th. Edition. P. 110 says this and I do not understand why.


Solution

  • Contrary to apparently popular belief, *p has type int. From [expr.unary.op]

    The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points. If the type of the expression is “pointer to T”, the type of the result is “T”.

    The reason decltype(*p) yields int& is because of how decltype works. From [dcl.type.simple]

    For an expression e, the type denoted by decltype(e) is defined as follows: [...]

    • otherwise, if e is an unparenthesized id-expression or an unparenthesized class member access, 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;

    • otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e;

    • otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e; [...]

    Here id-expression means an expression exactly consisting of a possibly parenthesized name.

    Since *p is an lvalue expression of type int and not an unparenthesized id-expression nor class member access, the third bullet applies and decltype(*p) is int&.

    It is worthy to note i is an unparenthesized id-expression, therefore the first bullet applies and decltype(i) is int.