Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

Quickly Check whether C++ Template Instances have the Same Parameters

5.00/5 (1 vote)
11 Feb 2012CPOL 6.9K  
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.

C++
// 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;
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)