我有一个模板类,它有几种类型。一种类型就是确定政策。该类确定函数在某些情况下的工作方式。
让我们说这是功能之一:
/* 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循环放在重载函数中,每个函数都采用具有特定策略类型的虚拟对象。但这意味着很多代码重复。使用模板特化的类似方法也会导致代码重复。
有没有办法在没有代码重复的情况下编译代码?
答案 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
。