http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53151
Bug #: 53151 Summary: [C++11] Incorrect type deduction in conditional expression Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: zeratul...@hotmail.com According to GCC, the type of T in the following is long: template <typename U> U&& declval(); typedef decltype(true ? declval<long>() : declval<long>()) T; I believe this is incorrect; the correct type of T is long&& The reasoning is as follows (with sections from N3291): - Section 5.2.2/10 says that the result of calling a function whose return type is an rvalue reference to an object type, is an xvalue. This tells us that declval<long>() is an xvalue. - Section 5.16/4 says that if the second and third operands to a conditional expression are glvalues of the same value category and the same type, the result is of that type and value category. In this case, both operands are xvalues of the same type, so the whole expression is an xvalue (note that xvalues are glvalues). - Finally, section 7.1.6.2/4 says that if e is an xvalue, decltype(e) is T&& where T is the type of e. It follows that the type of T should be long&&. Once this is corrected, an adjustment needs to be made to the implementation of the binary form of common_type: template<typename _Tp, typename _Up> struct common_type<_Tp, _Up> { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; }; should become: template<typename _Tp, typename _Up> struct common_type<_Tp, _Up> { typedef typename remove_reference<decltype(true ? declval<_Tp>() : declval<_Up>()) type>::type type; }; (The current implementation causes problems when trying to compile standard library headers with clang, as common_type<long, long>::type evaluates to long&& rather than long.)