在编译时删除/插入代码而不在C ++中重复

时间:2011-10-02 14:19:37

标签: c++ templates

我有一个模板类,它有几种类型。一种类型就是确定政策。该类确定函数在某些情况下的工作方式。

让我们说这是功能之一:

/* this code is part of a class */

    template <typename T, typename T_Policy> // Not important but just showing the template parameters of the class

    void Allocate(unsigned int numElements)
    {
      // Some code here
      while (someCondition) // Other functions don't have the loop, this is just an example
      {
        // Some code here

        if (T_Policy::trackElements) { /* some code here */ }
        if (T_Policy::verbose) { /* some code here */ }
        if (T_Policy::customManager) { /* some code here */ }
        /* and a few other policies */
      }
      // Some more code here
    }

我希望编译出使用策略的代码行,而不是依赖if语句。一种显而易见的方法是将while循环放在重载函数中,每个函数都采用具有特定策略类型的虚拟对象。但这意味着很多代码重复。使用模板特化的类似方法也会导致代码重复。

有没有办法在没有代码重复的情况下编译代码?

3 个答案:

答案 0 :(得分:3)

如果策略中的值是const,编译器可以优化生成代码,因为它可以看到if始终为true或始终为false。

答案 1 :(得分:1)

您可以随时更改代码

   if (T_Policy::trackElements) { /* some code here */ }

template <bool b>
void trackElementPhase() {
  /* some code here */
}

template <>
void trackElementPhase<false>() {} // empty body

 ... later in the code

     trackElementPhase<T_Policy::track_elements>();

当然T_Policy::track_elements必须是编译时间常量。

但是,我不会打扰。编译器可能足够聪明,可以优化

中的代码
   if (T_Policy::trackElements) { /* some code here */ }

如果条件是编译时间常量。

答案 2 :(得分:0)

您可以使用递归模板来制作所有应用的策略列表,例如:

#include <iostream>
template <typename Policy, typename Next=void>
struct policy_list {
  static void apply() {
    Policy::implement();
    Next::apply();
  }
};

template <typename Policy>
struct policy_list<Policy, void> {
  static void apply() {
    Policy::implement();
  }
};

struct first_policy {
  static void implement() { std::cout << "Policy 1" << std::endl;  }
};

struct second_policy {
  static void implement() { std::cout << "Policy 2" << std::endl; }
};

int main() {
  typedef policy_list<first_policy, policy_list<second_policy> > policy;
  while (1) {
    policy::apply();
  }
}

对于三种政策,您需要将typedef更改为:

typedef policy_list<first_policy, policy_list<second_policy, policy_list<third_policy> > > policy;

然后,您需要做的就是在编译时生成正确的策略列表。这可以通过构建系统的外部部分来生成,该部分生成带有typedef的头文件,或者可以使用预处理器或模板魔术来完成,具体取决于您的策略的确切含义。

如果你有C ++ 11可用,你可以使用可变参数模板简化policy_list