Quickly Check whether C++ Template Instances have the Same Parameters
How to quickly check whether C++ Template instances have the same parameters
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.
// This is code from Andrei Alexandresku book "Modern C++ Design", ch. 2
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
// Permission to use, copy, modify, distribute and sell this software for any
// purpose is hereby granted without fee, provided that the above copyright
// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
class NullType;
// Typelist
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 ..........................................................
// IndexOf
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 the typelist for all allowed types, e.g.
typedef TYPELIST_3(short, int, double) SL_TYPELIST;
// Base class
class Base
{
private: // Read only
int m_ID;
protected: // Nobody to play with it
Base(int ID = -1) : m_ID(ID) {}
public: // Must
virtual ~Base() {}
public:
int GetID(void) const {return m_ID;}
virtual bool IsRightType(Base* basePtr) = 0;
};
// Derived classes
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);}
};
// Use it in app:
int _tmain(int argc, _TCHAR* argv[])
{
Base* baseInt = new Child<int>;
Base* baseDbl = new Child<double>;
bool bChecInt = baseInt->IsRightType(baseInt); // Return true
bool bCheckDbl = baseInt->IsRightType(baseDbl); // Returns false
// Now do as you want: you know types
..........................................................
return 0;
}