views:

407

answers:

3

I am trying to implement a template class that would be able to tell me if a variable is a class,structure or a basic type.

So far I've come with this:

template< typename T >
class is_class
{
private:
    template< typename X >
    static char ( &i_class( void(X::*)() ) )[1];
    //
    template< typename X >
    static char ( &i_class( X ) )[2];
public:
    static bool const val = sizeof( i_class< T >(0) ) == 1;
};

and ussage:

is_class< int >::val; // false
is_class< some_class_type >::val; // true

The problem is that now I need to write a blank void function in every class that could be used with this code.

Does anyone know a solution to this problem?

A: 

Use boost's type traits.

Idan K
A: 

If it's only asserting during compile time, you could use BOOST_STATIC_ASSERT and Boost.TypeTraits to check if types are suitable. If you want to enable a template for specific types, you may have success using Boost's enable_if.

vividos
+8  A: 

is_class is a member of the Boost.Type_Traits library. The implementation is probably similar to what you already have. You would use in in conjunction with enable_if to create the function if appropriate:

template <class T>
   typename enable_if_c<boost::is_class<T>::value>::type 
     foo() {  }

Or the equivalent:

template <class T>
   typename enable_if<boost::is_class<T>>::type 
     foo() {  }

The function foo is only generated if the type T is of class type.

The return value for the function, if it is generated, is the second parameter (omitted) to the enable_if template (the default is void).

1800 INFORMATION
Note that is_class relies on non-standard compiler support to distinguish between classes and unions, with the result that it is often erroneously true for unions. That doesn't stop it correctly distinguishing between class and fundamental types, of course.
Steve Jessop