Introduction
To assign the permanent type-defined indexes to the derived classes inside the given hierarchy, use the TypeList
of all allowed for this hierarchy type and IndexOf
template. The base class has a data member int m_ID
. In this code, the class constructor is protected, so only descendants of this class can instantiate it as a base class inside the descendant. The virtual function of the descendant compares the m_ID
set at the construction of the descendant to the m_ID
of the parameter passed to the virtual function.
class NullType;
template <class T, class U>>
struct TypeList
{
typedef T Head;
typedef U Tail;
};
#define TYPELIST_1(T1) TypeList<T1, NullType>
#define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2)>
#define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3)>
#define ..........................................................
template <class TList, typename T> struct IndexOf;
template <typename T>
struct IndexOf<NullType, T>
{
enum { value = -1};
};
template <class Tail, typename T>
struct IndexOf<TypeList<T, Tail>, T>
{
enum {value = 0};
};
template <class Head, class Tail, typename T>
struct IndexOf<TypeList<Head, Tail>, T>
{
private:
enum {temp = IndexOf<Tail, T>::value};
public:
enum {value = temp == -1 ? -1 : 1 +temp};
};
typedef TYPELIST_3(short, int, double) SL_TYPELIST;
class Base
{
private: int m_ID;
protected: Base(int ID = -1) : m_ID(ID) {}
public: virtual ~Base() {}
public:
int GetID(void) const {return m_ID;}
virtual bool IsRightType(Base* basePtr) = 0;
};
template <typename T>
class Child : public Base
{
public:
Child():Base(IndexOf<SL_TYPELIST, T>::value) {}
virtual ~Child() {}
virtual bool IsRightType(Base* basePtr)
{return (basePtr->GetID() == IndexOf<SL_TYPELIST, T>::value);}
};
int _tmain(int argc, _TCHAR* argv[])
{
Base* baseInt = new Child<int>;
Base* baseDbl = new Child<double>;
bool bChecInt = baseInt->IsRightType(baseInt); bool bCheckDbl = baseInt->IsRightType(baseDbl); ..........................................................
return 0;
}