How to automatically register a class on creation

c++, design-patterns, idioms

Solution

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.

Problem

I was wondering whether a design pattern or idiom exists to automatically register a class type. Or simpler, can I force a method to get called on a class by simply extending a base class? For example, say I have a base class `Animal` and extending classes `Tiger` and `Dog`, and I have a helper function that prints out all classes that extend `Animal`. So I could have something like: ``` struct AnimalManager { static std::vector<std::string> names; static void registerAnimal(std::string name) { //if not already registered names.push_back(name); } }; struct Animal { virtual std::string name() = 0; void registerAnimal() { AnimalManager::registerAnimal(name()); } }; struct Tiger : Animal { virtual std::string name() { return "Tiger"; } }; ``` So basically I would do: ``` Tiger t; t.registerAnimal(); ``` This could be worked into a `static` function as well. Is there any pattern (like a curiously recursive template) or something like that that can help me achieve this without explicitly having to call the `registerAnimal` method. I want my `class Animal` to be extendible in the future and others might forget to call `register`, I'm looking for ways to prevent that besides documenting this (which I will anyway). PS This is just an example, I'm not actually implementing animals.

Original source