叮当是对的。N3337 §7.1.6.2/4:
表示的类型decltype(e)
定义如下:
- if
e
是无括号的id 表达式或无括号的类成员访问,decltype(e)
是由 命名的实体的类型e
。如果没有这样的实体,或者如果e
命名了一组重载函数,则程序是非良构的;
- 否则,如果
e
是一个 xvalue,decltype(e)
是T&&
,其中T
的类型是e
;
- 否则,如果
e
是左值,decltype(e)
是T&
,其中T
的类型是e
;
- 否则,
decltype(e)
是 的类型e
。
说明符的操作数decltype
是未计算的操作数。
§5/6:
[注意:表达式是一个 xvalue,如果它是:
- 调用函数的结果,无论是隐式还是显式,其返回类型是对对象类型的右值引用,
- 转换为对对象类型的右值引用,
- 一个类成员访问表达式,指定一个非引用类型的非静态数据成员,其中对象表达式是一个 xvalue,或
- 一个
.*
指向成员的表达式,其中第一个操作数是一个 xvalue,第二个操作数是一个指向数据成员的指针。
一般来说,这条规则的效果是命名的右值引用被视为左值,而对对象的未命名的右值引用被视为xvalue;对函数的右值引用被视为左值,无论是否命名。——<em>尾注]
我之前很谨慎,文字0
可能会以某种方式阻止它在这种情况下成为对象类型,但 §3.9/8 澄清了一些事情:
对象类型是(可能是 cv 限定的)类型,它不是函数类型,不是引用类型,也不是 void 类型。
条件运算符不会影响此处的任何内容 – §5.16/4:
如果第二个和第三个操作数是相同值类别的glvalues并且具有相同类型,则结果是该类型和值类别,并且如果第二个或第三个操作数是位域,则它是位域,或者如果两者都是位域。
在这种情况下,两者都属于相同的值类别(xvalue),xvalues 是 glvalues。