Почему decltype (a, b) оценивается ссылкой?

В соответствии с этим ответом ref должен быть int.

Но по какой-то причине он оценивается как int&, как в gcc, так и в MSVC2015, а decltype(b) правильно оценивается только int. Почему так?

int a = 1, b = 2;
decltype(a, b) ref; // ref is int&
decltype(b) var;    // var is int

Ответы

Ответ 1

a, b - это выражение. Согласно правилам decltype для выражений, если результат выражения равен lvalue, тип будет выводиться как T&

7.1.6.2/4 Спецификаторы простого типа [dcl.type.simple]
Для выражения e тип, обозначенный как decltype (e), определяется следующим образом:

  • если e - несферированное id-выражение или unparenthesized член класса (5.2.5), decltype (e) - тип объекта названный e. Если такой объект отсутствует или если e называет набор перегруженные функции, программа плохо сформирована;
  • в противном случае, если e является значением x, decltype (e) является T & &, где T - тип e;
  • в противном случае, если e является lvalue, decltype (e) является T &, где T - тип of e;
  • иначе, decltype (e) - тип e.

Сбивчивая часть о различии между "типом объекта, названным e" и "типом e", легко понять с помощью примера:

Если какой-либо объект e объявлен как int& e = x;, а затем в выражении e тип e равен int, а тип объекта с именем e - int&. Короче говоря, тип e отменяет эталонные квалификаторы.

Ответ 2

По той же причине, для которой decltype((a)) ref объявит ref как ссылку (int & вместо int).

decltype правила различаются, когда они имеют дело с выражениями, а не с сущностями. Категория значения выражения a, b является значением lvalue, поэтому decltype(a, b) дает T&int &.

См. также http://en.cppreference.com/w/cpp/language/decltype