
"Non-intrinsic version of `boost::is_convertible<int, int&>` returns true_type" is a BUG.
Yes it's a bug, but whether it's completely fixable is another matter (see comments below).
So, in Boost 1.47 and later versions, `boost::is_convertible<int, int&>` should return false_type.
Right.
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); };
Yep. Fixed in Trunk.
Also, `any_conversion` needs a constructor for an rvalue (Line 120):
template <typename T> any_conversion(const T&);
Yep, fixed in Trunk.
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.
It does, but it also terminally breaks C++03 compilers (not just gcc).
One note: The above code cannot deal with `boost::is_convertible<Func, Func&>`, where `Func` is a function type in a C++03 mode.
Not only that, it also breaks for abstract types, arrays, incomplete types, and anything else I've forgotten. I've fixed the issue for GCC in C++11 mode by forwarding to std::is_convertible, but it remains for now in C++03 mode. Note that other compilers are similarly effected *even when using a compiler intrinsic*, so for example given: 1) is_convertible<int&&, int&> 2) is_convertible<int, int&> MSVC fails (1) even though it's using a compiler intrinsic (and no we can't stop using it, that breaks other stuff). Intel on Win32 fails both 1 & 2, again using it's __is_convertible intrinsic. It seems to me that these related issues are basically unfixable without badly breaking something else, Regards, John.