If this helps, you can take a Hitesh answer and add:
struct luaRegisterManager { template <typename T> void registrate() { T::registrate();
Then:
int main() { luaRegisterManager lrm; lrm.registrate<someClass>(); lrm.registrate<someOtherClass>(); }
More generally, if you want to introduce any dynamic polymorphism in C ++, you need an object, not just a class. Thus, it is possible that various register functions should return objects with some common base class of the registeredClass or classRegistrationInfo or something in this direction.
Could it be an example of what you consider necessary for dynamic polymorphism? As I can see, the Hitesh code exactly matches your example, so this example should not cover all your expected use cases. If you write a code that will use it, it may become clear to you how to implement it, or someone can advise.
Something else that might help:
#include <iostream> #include <string> #include <vector> struct Registered { virtual std::string name() = 0; virtual ~Registered() {} Registered() { all.push_back(this); } static std::vector<Registered*> all; }; std::vector<Registered*> Registered::all; typedef std::vector<Registered*>::iterator Iter; template <typename T> struct RegisteredT : Registered { std::string n; RegisteredT(const std::string &name) : n(name) { T::registrate(); } std::string name() { return n; } // other functions here could be implemented in terms of calls to static // functions of T. }; struct someClass { static Registered *r; static void registrate() { std::cout << "registering someClass\n"; } }; Registered *someClass::r = new RegisteredT<someClass>("someClass"); struct someOtherClass { static Registered *r; static void registrate() { std::cout << "registering someOtherClass\n"; } }; Registered *someOtherClass::r = new RegisteredT<someOtherClass>("someOtherClass"); int main() { for (Iter it = Registered::all.begin(); it < Registered::all.end(); ++it) { std::cout << (*it)->name() << "\n"; } }
There are all kinds of problems with this code if you try to split it into several compilation units. In addition, such things lead to false messages from memory leak detectors if you also do not write any code to tear everything at the end or use the shared_ptr vector, acceleration pointer vector, etc. But you see the general idea that a class can "register itself" and that you need an object to make virtual calls.
In C ++, you usually try to avoid static initialization, although in favor of some kind of installation installation / dependency at the beginning of your program. Therefore, usually you simply list all the classes that interest you (by calling a function on each of them), rather than trying to do it automatically.