Template specialization based on inherit class

This article describes a neat trick: http://www.gotw.ca/publications/mxc++-item-4.htm

Here’s the basic idea. You first need an IsDerivedFrom class (this provides runtime and compile-time checking):

template<typename D, typename B>
class IsDerivedFrom
{
  class No { };
  class Yes { No no[3]; }; 

  static Yes Test( B* ); // not defined
  static No Test( ... ); // not defined 

  static void Constraints(D* p) { B* pb = p; pb = p; } 

public:
  enum { Is = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) }; 

  IsDerivedFrom() { void(*p)(D*) = Constraints; }
};

Then your MyClass needs an implementation that’s potentially specialized:

template<typename T, int>
class MyClassImpl
{
  // general case: T is not derived from SomeTag
}; 

template<typename T>
class MyClassImpl<T, 1>
{
  // T is derived from SomeTag
  public:
     typedef int isSpecialized;
}; 

and MyClass actually looks like:

template<typename T>
class MyClass: public MyClassImpl<T, IsDerivedFrom<T, SomeTag>::Is>
{
};

Then your main will be fine the way it is:

int main()
{
    MyClass<SomeTag>::isSpecialized test1; //ok
    MyClass<InheritSomeTag>::isSpecialized test2; //ok also
    return 0;
}

Leave a Comment