
On 12/9/2010 12:18 PM, Frédéric Bron wrote:
I made some progress in the implementation of operator traits. [...] 3. I have tried to use the existing is_convertible traits but without any success: The problem is that is_convertible expect a type as parameter, not an expression. So I have tried to get the return type of the operator with: a) boost result_of (but this does not work for arbitrary expression), b)boost typeof (but types must be registered first) c) with the following code:
#include<iostream> #include<boost/type_traits/is_convertible.hpp>
template<class To, class From> bool is_conv(const From&) { return boost::is_convertible< From, To>::value; };
Here, rather than returning a run-time true/false, return a compile-time true/false. I.e., use the sizeof trick. template< std::size_t N > struct sizeof_t { char _[N]; }; BOOST_MPL_ASSERT_RELATION( sizeof( sizeof_t<1> ), !=, sizeof( sizeof_t<2> ) ); template< class To, class From > sizeof_t< boost::is_convertible< const From&, To >::value + 1 > is_conv(const From&); [...]
but if I use is_conv(1+2) to set a value variable of type bool in the traits, the compiler complains that "is_conv(1+2)" is not a constant expression...
So now sizeof( is_conv< bool >(1+2) ) == sizeof( sizeof_t<2> ) is a static constant expression. It could also be useful to distinguish the const-qualifications of referents, i.e., add another overload of is_conv: template< class To, class From > sizeof_t< boost::is_convertible< From&, To >::value + 1 > is_conv(From&); And you can get even fancier if you want to distinguish between lvalues and rvalues (warning: untested): template< class From, class T > struct is_conv_result { typedef sizeof_t< boost::is_convertible< From, To >::value + 1 > type; }; template< class To, class From1, class From2 > typename is_conv_result< From1&, To >::type is_conv(From1&, From2&); // catches lvalue references-to-non-const template< class To, class From1, class From2 > typename is_conv_result< const From1&, To >::type is_conv(const From1&, From2&); // catches lvalue references-to-const template< class To, class From > typename is_conv_result< From, To >::type is_conv(const From&, ...); // catches rvalues You just need to pass the expression in question to both parameters of is_conv. HTH, - Jeff