typedef decltype(true ? (long&&)0 : (long&&)0) T;
应该是什么?
根据gcc(4.7),它很长.根据clang(主干),它是长&& ;.这种差异导致clang无法编译使用gcc 4.7的libstdc的代码.谁是对的?
更新:正如ildjarn指出的那样,Clang是对的,正如理查德史密斯指出的那样,错误libstdc是由于标准中的错误引起的.这是relevant GCC bug和relevant Defect Report.
解决方法:
Clang是对的. N3337§7.1.6.2/ 4:
The type denoted by
decltype(e)
is defined as follows:
- if
e
is an unparenthesized id-expression or an unparenthesized class member access,decltype(e)
is the type of the entity named bye
. If there is no such entity, or ife
names a set of overloaded functions, the program is ill-formed;- otherwise, if
e
is an xvalue,decltype(e)
isT&&
, whereT
is the type ofe
;- otherwise, if
e
is an lvalue,decltype(e)
isT&
, whereT
is the type ofe
;- otherwise,
decltype(e)
is the type ofe
.The operand of the
decltype
specifier is an unevaluated operand.
§5/ 6:
[ Note: An expression is an xvalue if it is:
- the result of calling a function, whether implicitly or explicitly, whose return type is an rvalue reference to object type,
- a cast to an rvalue reference to object type,
- a class member access expression designating a non-static data member of non-reference type in which the object expression is an xvalue, or
- a
.*
pointer-to-member expression in which the first operand is an xvalue and the second operand is a pointer to data member.In general, the effect of this rule is that named rvalue references are treated as lvalues and unnamed rvalue references to objects are treated as xvalues; rvalue references to functions are treated as lvalues whether named or not. —end note ]
我之前很谨慎,文字0可能会以某种方式阻止它在此上下文中作为对象类型进行限定,但§3.9/ 8澄清了一些事情:
An object type is a (possibly cv-qualified) type that is not a function type, not a reference type, and not a void type.
条件运算符不会影响这里的任何内容 – §5.16/ 4:
If the second and third operands are glvalues of the same value category and have the same type, the result is of that type and value category and it is a bit-field if the second or the third operand is a bit-field, or if both are bit-fields.
在这种情况下,两者具有相同的值类别(xvalue),并且xvalues是glvalues.