Search code examples
c++templatesc++17sfinaedecltype

Should decltype(1, t) be an l-value reference? (Compilers disagree)


Minimal code:

int t;
static_assert(is_same_v<decltype(1, t), int&>);

The above compiles in g++ and clang++ but fails in MSVC. MSVC seems to think:

int t;
static_assert(is_same_v<decltype(1, t), int>);

Which one does the standard specify? I rely on this pattern quite a bit for SFINAE.


Solution

  • Gcc and Clang are correct. 1, t is comma expression,

    The type, value, and value category of the result of the comma expression are exactly the type, value, and value category of the second operand, E2.

    The 2nd operand, i.e. t is an lvalue, then decltype would result in T&.

    If the argument is any other expression of type T, and

    • if the value category of expression is lvalue, then decltype yields T&;

    From the standard, [expr.comma]/1:

    (emphasis mine)

    The type and value of the result are the type and value of the right operand; the result is of the same value category as its right operand,

    and [dcl.type.decltype]/1.5

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

    BTW: I tried with MSVC here and got the same result with Gcc and Clang.