Reputation: 7837
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.
Upvotes: 14
Views: 5456
Reputation: 53047
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();
}
Upvotes: 13
Reputation: 2793
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;
}
Upvotes: 4