Search code examples
c++rttivariant

identifying the type


In my application, there is a inheritance hierarchy in which only the classes that are at the end of the inheritance chain are non-abstract classes. Also there is some usage of boost::variant. I want to write a function which takes a pointer and a Type and says whether the object belongs to that type.

For example

#define IsA(nodeptr, type)   ( checkType<type>(nodeptr) ) 

template<typename Type, bool isAbstract, typename PtrType >
class CheckType
{
    bool operator()( PtrType* ptr ) { return ( typeid(*ptr) == typeid(Type) ); }
};

template<typename Type, typename PtrType >
class CheckType < Type, true, PtrType >
{
    bool operator()( PtrType* ptr ) { return ( dynamic_cast<Type*>(ptr) != NULL ); }
};

template<typename Type, BOOST_VARIANT_ENUM_PARAMS(typename T) >
class CheckType< Type, false, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
    bool operator()( boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>* ptr ) 
    { 
        return ( ptr->type() == typeid(Type) ); 
    }
}

template< typename Type, typename PtrType >
bool checkType( PtrType* nodePtr )
{
    CheckType<Type, boost::is_abstract<PtrType>::value, PtrType> check;
    return check(nodePtr);
}

Now if there is a boost variant, i want to find out whether the boost variant stores that particular type. Can someone help me with that? I don't want to add an extra parameter to find out whether it is a variant. Even for finding out the abstractness, i am using boost::is_abstract..

Thanks, Gokul.


Solution

  • Well there are two direct versions of this:

    return (boost::get<Type*>(v) != 0);
    

    And this:

    return ( v.type() == typeid(Type) );
    

    I am not sure how to handle that with your template overloading cleanly but you could do something like this:

    template< typename Type, bool TypeisAbstract, bool TypeIsVariant,
              typename ptrType >
    bool checkType( ptrType* t)
    {
        return ( typeid(*t) == typeid(Type) );
    }
    
    template< typename Type, typename ptrType >
    bool checkType<Type, true, false, ptrType>( ptrType* t)
    {
        return ( dynamic_cast<Type*>(t) != NULL );
    }
    
    template< typename Type>
    bool checkType<Type, false, true, ptrType>(const boost::variant& v)
    {
        return ( v.type() == typeid(Type) );
    }