【问题标题】:c++ template specialization based on compile time value基于编译时间值的 c++ 模板特化
【发布时间】:2012-05-28 12:36:57
【问题描述】:

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

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

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

【问题讨论】:

    标签: c++ templates metaprogramming compile-time-constant


    【解决方案1】:

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

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

    【讨论】:

    • 完美运行!谢谢Pubby
    【解决方案2】:

    这里的聚会很晚了,但是。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多