我有一个算法,它需要大量参数(即配置)作为其构造函数的一部分,并且还需要一些明确定义的创建步骤。因此,我创建了一个Builder Pattern实现,它允许设置所需的参数并创建中间和最终实例,例如
// 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 中被称为值对象或 Bean。新的 Builder 将是这样的:
// 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
那时还不知道。