14

According to this answer, ref should be an int.

But for some reason it evaluated to int&, both in gcc and MSVC2015, while decltype(b) is correctly evaluated to just int. Why so?

int a = 1, b = 2;
decltype(a, b) ref; // ref is int&
decltype(b) var;    // var is int
Community
  • 1
  • 1
Starl1ght
  • 4,422
  • 1
  • 21
  • 49
  • 1
    Perhaps `decltype(expr)` makes an lvalue-rvalue conversion (not ODR-used) of its expression, but, again, perhaps, the second expression, `b` doesn't do it due to the comma operator, so, `b` remains as a lvalue, being its corresponding type a reference. – ABu Jun 26 '16 at 18:16

2 Answers2

17

a, b is an expression. According to decltype rules for expressions, if result of the expression is an lvalue, type is going to be deduced as T&

7.1.6.2/4 Simple type specifiers [dcl.type.simple]
For an expression e, the type denoted by decltype(e) is defined as follows:

  • if e is an unparenthesized id-expression or an unparenthesized class member access (5.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;
  • 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;
  • otherwise, decltype(e) is the type of e.

The confusing part about difference between "type of the entity named by e" and "type of e" is easy to understand with example:

If some entity e is declared as int& e = x;, then later, in expression e, type of e is int, and type of the entity named by e is int&. In short, type of e drops reference qualifiers.

Revolver_Ocelot
  • 8,609
  • 3
  • 30
  • 48
  • 1
    `a` is an lvalue as well, however, `decltype(a)` is deduced as just `int`, not `int&`. – ABu Jun 26 '16 at 18:17
  • 2
    @Peregring-lk There is an specific rule for entity name. Standard quote in a second. – Revolver_Ocelot Jun 26 '16 at 18:19
  • Can you produce a citation that "the type of `e`, where `int& e = x;`, is `int`"? – Yakk - Adam Nevraumont Jun 26 '16 at 18:54
  • @Yakk 5/5 [expr] _If an expression initially has the type “reference to T”, the type is adjusted to T prior to any further analysis._ `e` is a primary expression (_id-expression_), so its type is adjusted to not contain any references. Hence point 1, which exist to avoid that in _id-expression_ s – Revolver_Ocelot Jun 26 '16 at 19:11
  • For `decltype(b)` the important part is "if e is an **unparenthesized id-expression**". For `decltype(a, b)` the following dots. (See also the answer of @peppe) –  Jun 26 '16 at 19:13
8

By the same reason for which decltype((a)) ref would declare ref as a reference (int &, instead of int).

decltype rules are different when they deal with expressions rather than entities. The value category of the a, b expression is a lvalue, hence decltype(a, b) yields T& -> int &.

See also http://en.cppreference.com/w/cpp/language/decltype

peppe
  • 21,934
  • 4
  • 55
  • 70