
(CC'ing John Maddock) "Non-intrinsic version of `boost::is_convertible<int, int&>` returns true_type" is a BUG. In Boost 1.46 and prior versions, the doc of is_convertible says If an imaginary lvalue of type From is convertible to type To then inherits from true_type, So the behavior is correct in these versions. But, in later versions, the doc says If an imaginary rvalue of type From is convertible to type To then inherits from true_type, Also, here is the "History" section of the doc Boost 1.47.0 * Breaking change: changed is_convertible to C++0x behaviour when possible. (TR1's is_convertible is equivalent to the old Boost one. C++11's is_convertible is different from them; see N2255.) So, in Boost 1.47 and later versions, `boost::is_convertible<int, int&>` should return false_type. Below, I'll show the bug fix using the non-intrinsic version for gcc. The bug is caused by the following code (Line 132): template <typename From, typename To> struct is_convertible_basic_impl { static typename add_rvalue_reference<From>::type _m_from; static bool const value = sizeof( boost::detail::checker<To>::_m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type); }; Here, `_m_from` is not treated as an rvalue. The correct code is template <typename From, typename To> struct is_convertible_basic_impl { static bool const value = sizeof( boost::detail::checker<To>::_m_check(boost::declval<From>(), 0) ) == sizeof(::boost::type_traits::yes_type); }; Also, `any_conversion` needs a constructor for an rvalue (Line 120): template <typename T> any_conversion(const T&); Finally, in `is_convertible_impl`, we shouldn't use `ref_type` in Line 299. Just using `From` is correct: boost::detail::is_convertible_basic_impl<From,To>::value With these changes, `boost::is_convertible<int, int&>` on gcc returns false_type. One note: The above code cannot deal with `boost::is_convertible<Func, Func&>`, where `Func` is a function type in a C++03 mode. This results in a compiler error. (In a C++11 mode, it returns true_type.) `boost::is_convertible<void, void>` results in a compiler error in both C++03 and C++11 modes. If these needs to be supported, we have to add special treatment codes. Regards, Michel