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.