I noticed that is_class actually detects classes only for the Metrowerks and the VC++, other compilers use a fall-back implementation which works by detecting everything but classes and thus everything which remains has to be a class. This is IMHO broken as i.e. member functions are detected as classes.
I have an implementation which works for both the GCC (3.0+ I think) and the Intel 6/7 compiler (thus probably for most comparable EDG-based compilers), I wonder if there is any interest in it and if my implementation and the current one can be combined (or if my version works for the MW and the VC, too). Here is the non-boostified code which can IMHO be easily adapted (I tried to copy all relevant parts from my header, I hope it's complete enough to understand it): typedef char (&yes_t)[ 1 ]; typedef char (&no_t)[ 2 ]; // is_function template< typename T > struct is_function { private: struct detail { static yes_t test( ... ); static no_t test( const volatile void* ); }; public: enum { value = sizeof detail::test( static_cast< T* >( 0 ) ) == sizeof( yes_t ) }; }; template< typename T > struct is_function< T& > { enum { value = false }; }; // remove_const template< typename T > struct remove_const { typedef T type; }; template< typename T > struct remove_const< const T > { typedef T type; }; // remove_volatile template< typename T > struct remove_volatile { private: template< bool, typename U > struct select { typedef U type; }; template< typename U > struct select< true, volatile U > { typedef U type; }; template< typename U > struct select< true, U& > { typedef U& type; }; public: typedef typename select< !is_function< T >::value, T >::type type; }; // remove_cv template< typename T > struct remove_cv { typedef typename remove_const< typename remove_volatile< T >::type >::type type; }; // Based on Paul Mensonides' technique found at // http://groups.google.com/groups?selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a // detail::is_class::test namespace detail { namespace is_class { template< typename > mfl::no_t test( ... ); template< typename T > mfl::yes_t test( void (T::*)() ); } } // is_class (note that a union is detected as a class, // I know of no way to separate unions from non-unions) template< typename T > struct is_class { private: template< bool, typename > struct test { enum { value = false }; }; template< typename U > struct test< true, U > { enum { value = sizeof detail::is_class::test< U >( 0 ) == sizeof( yes_t ) }; }; public: enum { value = test< !is_function< T >::value, typename remove_cv< T >::type >::value }; }; This not only leads to safer class detection, it also allows us to implement is_member_function without providing versions for every number of parameters. Omitting some of the intermediate type-traits, here's how it may look: template< typename T > struct is_member_function_pointer { private: template< bool, typename > struct test { enum { value = false }; }; template< typename U > struct test< true, U > { enum { value = !is_class< U >::value && !is_enum< U >::value && !is_member_variable_pointer< U >::value }; }; public: enum { value = test< !is_fundamental< T >::value && !is_reference< T >::value && !is_pointer< T >::value && !is_array< T >::value && !is_function< T >::value, T >::value }; }; template< class C, typename T > struct is_member_function_pointer< T C::* > { enum { value = is_function< T >::value }; }; template< class C, typename T > struct is_member_function_pointer< T C::* const > { enum { value = is_function< T >::value }; }; template< class C, typename T > struct is_member_function_pointer< T C::* volatile > { enum { value = is_function< T >::value }; }; template< class C, typename T > struct is_member_function_pointer< T C::* const volatile > { enum { value = is_function< T >::value }; }; This may look overly complex, but this is due to the fact that the GCC and the Intel compiler disagree about certain type deductions. The above version combines both behaviours without the need for #ifdef. There are probably some other things, but is_class is IMHO an important one, thus I would like to see if there is interest in fixing it. Comments? Regards, Daniel _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost