【发布时间】:2014-02-05 05:05:16
【问题描述】:
我有一些结构如下的现有代码:
class IRule
{
public:
virtual ~IRule() {}
virtual void Begin(int value) = 0;
virtual double Evaluate(Context& context) = 0;
};
class RuleA : public IRule
{
// concrete implementation
};
// more rules; note many require non-default construction and extra setup
class CompositeRule : public IRule
{
public:
// called any number of times to add child rules
void Add(IRule *rule) { rules.push_back(rule); }
virtual void Begin(int value) { /* for each rule, call Begin */ }
virtual double Evaluate(Context& context)
{
/* for each rule, call Evaluate and sum the results */
}
private:
std::vector<IRule*> rules;
};
void DoSomething(IRule *rule)
{
rule->Begin(x);
ProcessResult(rule->Evaluate(y));
}
当然,DoSomething 可以被赋予单个规则或某些规则组合。此代码有效,但它需要分配内存来创建和填充CompositeRule(对于虚拟对象本身和包含它们的向量),并且这是在导致性能问题的循环中发生的。 (将规则构造移到循环之外是不可行的。)
我想通过将CompositeRule 替换为模板类来解决此问题,该模板类直接保存其每个子规则具体类型的实例(因此它可以在堆栈而不是堆上构建)。虽然DoSomething 是从几个不同的地方用不同的规则集调用的,但在每个调用站点,这个集合在编译时是固定的,所以这应该是可行的。 (甚至可能完全移除虚拟基础,尽管这需要将 DoSomething 设为模板,而且我不确定是否要这样做。)
写这类东西的最佳方式是什么,Boost 中有什么东西可以帮助解决这个问题吗? (MPL、Tuple 和 Fusion 似乎是可能的候选者,但我从来没有真正玩过它们。)我假设我可能必须使所有规则默认可构造,但如果有某种方法可以给构造函数- 构造复合材料时将参数设置为单个规则,那会很好。 (我怀疑这要么需要 C++11 转发,要么会变得非常丑陋,所以我可以不这样做。)
【问题讨论】: