У меня есть существующий код структуры, как это:Замена композитных виртуальных шаблонов с
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 или получилось бы действительно уродливым, хотя, так что я в порядке с этим не делаю.)
Просто заметил тег [tag: C++ 03], поэтому [** вот версия C++ 03: ** coliru.stacked-crooked.com/a/16f97e40c0827777] (http://coliru.stacked-crooked.com/a/16f97e40c0827777) – sehe
Выглядит намного приятнее. Я попробую это завтра. – Miral
Кажется хорошо работать. Однако производительность не так сильно улучшилась, как я бы надеялся. Я думаю, что распределитель памяти был более эффективным, чем я ожидал. – Miral