Каков правильный результат decltype ((A {}. Int_member))?

Учитывая определение типа A:

struct A { int i; };

В соответствии со спецификацией [expr.ref] (я использовал n4618):

(если E2 не ссылается,)... Если E1 является lvalue, то E1.E2 является lvalue; иначе E1.E2 - это значение x...

очевидно A{}.i - значение x;  также учитывая, что [dcl.type.simple]:

(для decltype(e),) -... if e - это несферированное id-выражение или unparenthesized доступ к члену класса... - в противном случае, если e является значением x, decltype (e) является T & &, где T является типом e

поэтому decltype( ( A{}.i ) ) должен давать int &.

Однако я пробовал GCC5.1 и Clang3.9, они дают int, а vs2015u3 дает int &. Что правильно?

Ответ 1

int&& правильный.

Слова, приведенные в [expr.ref], были изменены пару лет назад cwg 616 и не были немедленно приняты реализации; см. мой ответ здесь. В основном, компиляторы должны были принять DR 616 и документ по временным выражениям одновременно, иначе они сломают код, в котором требуется продление жизни объекта, где мы привязываем ссылку на элемент объекта. В старой модели реализаций только prvalues ​​могут обозначать объекты, для которых пожизненное расширение является жизнеспособным (хотя такое требование не существовало в формулировке, как указывал Йоханнес, это была неопределенная формулировка до N3918, так что...).