13

我正在慢慢进入模板元编程,但我不确定如何实现以下内容:

// 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>();

在编译时,我会知道第三个模板类型是什么枚举值(编译时不变),要么死要么活。是否可以为 Register 函数定义两个主体,例如:

// 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 ...  }

我看过: C++ Template Specialization with Constant Value

但我一直无法弄清楚如何使其适用于这种情况。

4

2 回答 2

13

模板函数不能部分特化。解决方案是将其包装在一个结构中:

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();
}
于 2012-05-22T02:32:04.130 回答
3

在这里聚会很晚,但是。

我认为在概念上更简单且更易于阅读的一种方法是简单地将枚举的不同值设置为不同类型(在命名空间内,以保持干净),并利用(模板)函数重载:

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;
}

你这样称呼他们:

int main() {
   Register<int,int>(State::Dead());
   Register<int,int>(State::Alive());
   return 0;
}
于 2017-02-09T09:55:10.430 回答