Generate Classes with Names from Template Parameter?

Viewed 32

Is it possible to use a template to create classes with names and some init options given as template parameters?

As a macro, this would be straightforward:

#define make_class(NAME, INIT) \
  class NAME : public Base  \
  {                         \
    NAME () : Base()        \
    {                       \
      base_init(INIT);      \
    }                       \
  };

make_class(Class1, {1, 0})
make_class(Class2, {0, 1})

But this template can't work, can it?

template<typename NAME, std::vector<int> INIT>
class NAME : public Base
{
public:
  NAME () : Base()
  {
    base_init(INIT);
  }
};

And how to generate the class instances Class1, Class2, etc.? Would one need to wrap this into a holding class and use using to shortcut the names with template parameters?

1 Answers

OK, the literal answer is indeed "that's not possible with templates", but practically it can be achieved by namespace-level type aliases with using, and a templated (intermediate) base class. Also, the std::vector as template argument is not possible, only a fixed list of constants.

Full example:

#include <iostream>

template<int a = 0, int b = 0>
class Base
{
public:
  Base()
  {
    base_init(a, b);
  }
    
  void base_init(int _a, int _b)
  {
    std::cout << "init a " << _a << " b " << _b << std::endl;
  }
};

using Class1 = Base<1, 0>;
using Class2 = Base<0, 1>;

int main()
{
  Class1 c1;
  Class2 c2;
}

Output:

init a 1 b 0
init a 0 b 1
Related