-1

I have a large number of subclasses which subscribe to various events such as initialization and entity deletion.

Currently I solve this by doing

class A{ static void init(); void kill(ID); }
class B{ static void init(); void kill(ID); }
class C{ static void init(); void kill(ID); }
A::init();
B::init();
C::init();

Which, with a multiline editor isn't difficult, and is trivial to read, but there's lots of room for mistakes, mostly remembering to add each new class to the invoking section, instead of the class adding itself as it would with dynamic polymorph.

How do I use static polymorphy to get this into a form resembling

//interface, with default behavior implementation
class W{ static void init(){...} void kill(ID){...} }

class A : W<A> {}
class B : W<B> { static void init(){...} }

constexpr auto w_classes = magic_classlist(A, B, ...)

w_classes::init();

With objects-methods, making a list of static_casted objects is easy.
But I need classes-functions. So to make an iterable list of classes, without manually adding them to a template, ideally by inheriting the superclass, if possible.

Khlorghaal
  • 230
  • 2
  • 11
  • Historically this was solved with a factory design pattern, see https://stackoverflow.com/questions/5120768/how-to-implement-the-factory-method-pattern-in-c-correctly – Mikhail May 06 '18 at 23:18
  • Rewriting this code in the manner that would not require to add classes manually would eventually lead to the bigger and more difficult problem - figuring out which classes are self-adding. Eliminating repetitive init / kill code would be easy - just keep a tuple of classes (or some other kind of type lists) and invoke a method for each. – user7860670 May 06 '18 at 23:26
  • the distinction here is that I want to do this at compile time, without virtuals – Khlorghaal Sep 16 '18 at 04:51

1 Answers1

2

Maybe the following is enough for you:

template <typename ... Ts>
class magic_classlist
{
    static void init()
    {
        (Ts::init(), ...); // C++17, but can be done for C++11
    }
};

and then:

constexpr auto w_classes = magic_classlist<A, B, ...>();

w_classes::init();
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • I tried doing similar with a macro for applying a lambda to a variadic list of tokens, but variadic macro syntax is prohibitively arcane so I did settle on this. I still have to explicitly initialize static members which is annoying, but I guess thats just the cost of this method. – Khlorghaal Sep 17 '18 at 18:56