Каков правильный результат 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, так что...).