
I have been tracking down an issue with some of my code which compiles fine with gcc but not clang. It manifested as a failure in Boost.Parameter but I eventually pinned it down to an inconsistency in the behaviour of boost::is_convertible. The following program demonstrates the issue: ============== #include <boost/type_traits/is_convertible.hpp> #include <boost/static_assert.hpp> class A {}; int main() { BOOST_STATIC_ASSERT((boost::is_convertible<A, A&>::value)); } ============== This compiles fine under g++ (4.7.1), but the assertion fires under clang++ (r160940). This is not too surprising because is_convertible is implemented in completely different ways on the two compilers: - on clang it is in terms of the __is_convertible intrinsic, which behaves like std::is_convertible and fails because rvalue references don't convert to lvalue references. - on gcc it has a complex custom implementation which at some point performs add_reference<> on the first argument and thus determines that the conversion is OK. Reading the docs for boost::is_convertible I think the clang interpretation is closer to the intention, in which case the gcc implementation is wrong, and so is Boost.Parameter (which relies on this behaviour). On the other hand, I suspect there's probably other code out there that depends on this in a similar way to Boost.Parameter, so perhaps it would be safer to tweak the clang implementation instead, and deviate from std::is_convertible. Any thoughts? John Bytheway