I have an algorithm that requires a large number of parameters (i.e. configuration) as part of its constructor and also requires some clearly defined creational steps. Therefore I have created a Builder Pattern implementation that allows to set the needed parameters and create the intermediate and final instance e.g.
// somewhere
class SomeAlgo {
public:
SomeAlgo(double a, double b, double c, double d, double e /* etc */);
;
Now I define the Builder to be e.g.
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
};
At this point everything looks ok but now I would like to Pull Up
the setters of the builder into a SomeAlgoConfig
class so that I can also cover the use-case of passing around a simple configuration instead of a convoluted long list of parameters. This simple configuration is what in Java is known as a Value Object or Bean. The new Builder would be like this:
// 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;
};
Now the SomeAlgoConfig
implementation:
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
}
and the intent is to be used like this:
SomeAlgoConfig config; // <<< here it won't compile because it misses the T parameter
config.setA(a).setB(b).setC(c);
This will do the trick I guess. However, whenever I'd like to use SomeAlgoConfig
on its own (outside the context of a Builder) e.g. to pass it as parameter I need to declare it with a template parameter which would be itself SomeAlgoConfig<SomeAlgoConfig>
. How can I define it in a way that it defaults to itself as template type? e.g. doing this doesn't work: template<typename T = SomeAlgoConfig> class SomeAlgoConfig
because the SomeAlgoConfig
is not yet known at that point.