Вопрос шаблона C ++, чтобы вывести шаблон Builder в конфигурацию?

У меня есть алгоритм, который требует большого количества параметров (то есть конфигурации) как часть его конструктора, а также требует некоторых четко определенных этапов создания. Поэтому я создал Образец Строителя реализация, которая позволяет установить необходимые параметры и создать промежуточный и конечный экземпляр, например,

// somewhere
class SomeAlgo {
public:
SomeAlgo(double a, double b, double c, double d, double e /* etc */);
;

Теперь я определяю Строителя как, например.

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 известно как объект значения или бин. Новый Строитель будет выглядеть так:

// 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 самостоятельно (вне контекста строителя), например чтобы передать его в качестве параметра, мне нужно объявить его с параметром шаблона, который был бы сам SomeAlgoConfig<SomeAlgoConfig>, Как я могу определить его так, чтобы он по умолчанию использовался как тип шаблона? например делать это не работает: template<typename T = SomeAlgoConfig> class SomeAlgoConfig поскольку SomeAlgoConfig на данный момент еще не известно.

0

Решение

Config должен быть похож на контейнер для параметров, поэтому вам не нужно менять конструкторы и установщики всякий раз, когда вы передумаете о параметрах, которые хотите передать. Делать сборку наследником конфигурации не имеет смысла, потому что строитель не является конфигурацией, а «Мне нужны унаследованные методы» не является допустимым аргументом для реализации этого в вашем проекте. Вы можете сделать конфиг членом сборщика и вызвать:

builder.getConfig().setA(a);
builder.getConfig().setB(b);
//...
builder.createResult();

Если вы хотите иметь конфигурацию шаблона, вы бы также сделали шаблон компоновщика, например:

template<class T>
class AlgoBuilder<T>{
//...
private:
AlgoConfig<T> config;

Таким образом, вы можете установить pass config в конструкторе.

По поводу вашего вопроса об отсутствии параметра T при создании экземпляра конфигурации … Ну, на этом этапе, так как вы хотите установить a, b, c и все другие параметры, вы уже знаете тип параметров, так что вы можете фактически создать экземпляр Конфиг с типом T, который является тем же типом ваших параметров. AlgoConfig< AlgoConfig> не имеет для меня особого смысла.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]