У меня есть алгоритм, который требует большого количества параметров (т. Е. Конфигурации) как часть его конструктора, а также требует определенных четко определенных шагов создания. Поэтому я создал реализацию Builder Pattern, которая позволяет установить необходимые параметры и создать промежуточный и конечный экземпляр, например.Проблема с шаблоном C++ для вытягивания шаблона Builder в конфигурацию?
// somewhere
class SomeAlgo {
public:
SomeAlgo(double a, double b, double c, double d, double e /* etc */);
;
Теперь я определяю Builder как, например,
class SomeAlgoBuilder {
public:
SomeAlgo& createResult() { /* TODO: */ }
virtual SomeAlgoBuilder& creationStep1() = 0;
virtual SomeAlgoBuilder& creationStep2() = 0;
virtual SomeAlgoBuilder& creationStep3() = 0;
// example setter note the builder returns *this
SomeAlgoBuilder& setA(double a) { a_ = a; return *this; }
SomeAlgoBuilder& setB(double b) { b_ = b; return *this; }
// etc
};
На данный момент все выглядит нормально, но сейчас я хотел бы Pull Up
сеттеров строителя в SomeAlgoConfig
класс, так что я могу также покрыть потребительной случай прохождения вокруг простой конфигурации вместо запутанных долго список параметров. Эта простая конфигурация - это то, что в Java известно как объект Value или Bean. Новый строитель будет выглядеть так:
// not "is a" config but need the implementation inheritance
// >>>>>> note the need to pass SomeAlgoBuilder as template
class SomeAlgoBuilder : private SomeAlgoConfig<SomeAlgoBuilder> {
public:
SomeAlgo& createResult() { /* TODO: */ }
virtual SomeAlgoBuilder& creationStep1() = 0;
virtual SomeAlgoBuilder& creationStep2() = 0;
virtual SomeAlgoBuilder& creationStep3() = 0;
};
Сейчас SomeAlgoConfig
реализация:
template<T>
class SomeAlgoConfig {
T& setA(double a) { a_ = a; return *static_cast<T*>(this); }
T& setB(double b) { b_ = b; return *static_cast<T*>(this); }
// etc
}
и намерение состоит в том, чтобы использовать так:
SomeAlgoConfig config; // <<< here it won't compile because it misses the T parameter
config.setA(a).setB(b).setC(c);
Это будет делать трюк я Угадай. Однако всякий раз, когда я хотел бы использовать SomeAlgoConfig
самостоятельно (вне контекста Builder), например. передать его как параметр Мне нужно объявить его с параметром шаблона, который сам будет SomeAlgoConfig<SomeAlgoConfig>
. Как я могу определить его таким образом, что он по умолчанию сам по себе является типом шаблона? например делать это не работает: template<typename T = SomeAlgoConfig> class SomeAlgoConfig
, потому что SomeAlgoConfig
еще не известен в этой точке.
спасибо. Именно здесь я пытался сходиться, сводя к минимуму количество необходимых мест, когда параметры менялись. Я также считаю ваше решение очень чистым и элегантным. Благодаря! –