Question

I'm feeling my way into template meta-programming, slowly and I'm not sure how to implement the following:

// hpp file
enum MyEnum { Alive = 0, Dead };
class A {
    public:
        template<typename T, typename O, MyEnum ls>
        static int Register();
};

// elsewhere in the code...
A::Register<IType1, Type1, Dead>();

At compile time I will know what enum value the third template type is (compile-time invariant), either Dead or Alive. Is it possible to define two bodies for the Register function, something like:

// desired hpp file
template<typename T, typename O, Alive>
int Register();

template<typename T, typename O, Dead>
int Register();

// corresponding desired .inc file
template<typename T, typename O, Alive>
int Register() { // Alive specific implementation ...  }

template<typename T, typename O, Dead>
int Register() { // Dead specific implementation ...  }

I have taken a look at: C++ Template Specialization with Constant Value

but I have not been able to figure out how to make it apply to this situation.

Was it helpful?

Solution

Template functions can't be partially specialized. The solution is to wrap it in a struct:

template<typename T, typename O, MyEnum ls>
struct foo;

template<typename T, typename O>
struct foo <T, O, Alive> {
  static int Register() {
    // ...
  }
};

template<typename T, typename O>
struct foo <T, O, Dead> {
  static int Register() {
    // ...
  }
};

template<typename T, typename O, MyEnum ls>
int Register() {
  return foo<T, O, ls>::Register();
}

OTHER TIPS

Very late to the party here, but.

A way to do this that I think is conceptually simpler and also easier to read is simply making the different values of your enum different types (inside a namespace, to keep it clean), and take advantage of (template) function overloading:

namespace State {
  struct Dead {};
  struct Alive {};
}

template<typename T, typename O>
int Register(State::Dead) {
   return 1;
}

template<typename T, typename O>
int Register(State::Alive) {
   return 2;
}

You call them like this:

int main() {
   Register<int,int>(State::Dead());
   Register<int,int>(State::Alive());
   return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top