Should this program print 0 or 1? In my reading and understanding of the quoted paragraphs from the C ++ 14 standard, it should print 1, but both GCC and clang print 0 (because the deduced type is A const instead of A const& ):
In this case, ra is A const lvalue, and std::move(a) is A xvalue, both types of the class. According to the standard on the conditional operator (my selection), the result should be an lvalue type A const , and therefore, the decltype result should be A const& :
[expr.cond] / 3 Otherwise, if the second and third operands are of different types but have a (possibly cv-qualified) class of type , or if both are values ββof the same category of values ββof the same type, except cv-qualifications, an attempt is made to convert each of these operands to the type of the other. The process of determining whether it is possible to transform the expression E1 of the operand of type T1 into correspondence with the expression of the operand E2 of type T2 is defined as follows:
- If E2 is an lvalue : E1 can be converted to E2, if E1 can be implicitly converted (clause 4) to type "lvalue reference to T2" , provided that the link must be directly linked (8.5.3) with lvalue during conversion .
[...]
In this case, E2 is ra , which is the value of l, and the other can be implicitly converted to a "T2 reference value" , as shown in line // #1 . "reference to the value of T2" is translated as A const& , therefore std::move(a) bound directly to an lvalue of type A const , and after conversion both operands have the same type and category of values, and thus:
[expr.cond] / 3 If the second and third operands are glvalues ββof the same category of values ββand have the same type, the result refers to the type and category of values ββ[...].
So, the result of the statement should be lvalue, and the result of decltype should be a reference, and therefore, the program should print 1.