How to automatically register a class on creation

You can indeed do this using the curiously recursive template idiom. It requires nothing from whoever is extending the class that can’t be enforced by the compiler:

template<class T>
struct Animal
{
   Animal()
   { 
      reg;  //force specialization
   }
   virtual std::string name() = 0;
   static bool reg;
   static bool init() 
   { 
      T t; 
      AnimalManager::registerAnimal(t.name());
      return true;
   }
};

template<class T>
bool Animal<T>::reg = Animal<T>::init();

struct Tiger : Animal<Tiger>
{
   virtual std::string name() { return "Tiger"; }
};

In this code, you can only extend Animal if you specialize it. The constructor forces the static member reg to be initialized, which in turn calls the register method.

EDIT: As pointed out by @David Hammen in the comments, you won’t be able to have a collection of Animal objects. However, this can easily be solved by having a non-template class from which the template inherits and use that as a base class, and only use the template for extending.

Leave a Comment