[英]c++ templatizing class constructor
我有一个类,它的构造函数带有很多参数
enum class FooType {FOO_A, FOO_B, FOO_C};
class Foo {
Foo(const double a, const double b, .... const double n);
}
根据“类型”,我只需要参数的某个子集。 目前,有各种构造函数的输入数量不同,但是将添加一些新类型,以使输入数量相同。 我可以将类型添加到构造函数中,在其中进行很长的切换,但是params列表很长。
Foo(FooType type, const double a, const double b, .... const double n) {
if (type = FooType::FOO_A) {
...
} else if ....
}
似乎还不错,但是我也不喜欢有那么长的参数列表。 似乎很容易产生错字,这是调试的麻烦。 所以我可以a。)在b。中传递结构)做其他事情
我只是对潜在的b解决方案感到好奇。
是否可以对此进行模板化,以便我可以创建模板构造函数并使用类似以下内容的方式调用构造函数
std::make_shared<Foo<FooType::FOO_A>>(a, b, c);
注意:我不想使用继承,因为该类的其余功能绝对不需要/不需要它。
这可能是命名参数惯用法的用例: http : //www.cs.technion.ac.il/users/yechiel/c++-faq/named-parameter-idiom.html 。
那将使您的构造函数调用看起来像这样:
File f = OpenFile("foo.txt")
.readonly()
.createIfNotExist()
.appendWhenWriting()
.blockSize(1024)
.unbuffered()
.exclusiveAccess();
代替上面的示例,您可以有一个包含所有已命名参数的帮助程序类,并且您的类构造函数将参数类的实例作为其参数。
这使您可以自由选择在构造时初始化的参数集。 如果要强制为不同类型初始化不同的子集,则应只编写不同的构造函数版本。
这是使用构建器模式制作模板化构造函数的方法:
class Foo {
double a;
int b;
double c;
public:
Foo(double a, int b, char c) {
}
};
template <FooType Type>
class Builder { };
template <>
class Builder<FooType::FOO_A> {
double _a;
public:
Builder& a(double val) { _a = val; return *this; }
Foo build() { return { _a, 0, 0 }; }
};
template <>
class Builder<FooType::FOO_B> {
int _b;
public:
Builder& b(int val) { _b = val; return *this; }
Foo build() { return { 0.0, _b, 0 }; }
};
template <>
class Builder<FooType::FOO_C> {
char _c;
public:
Builder& c(char val) { _c = val; return *this; }
Foo build() { return { 0.0, 0, _c }; }
};
可以根据需要对Builder
类进行模板化,并在if语句中执行代码,您可以在builder的构造函数中执行,也可以在要返回的Foo
实例上的build
函数中执行。
在示例中, a
与FOO_A
有关, b
与FOO_B
有关, c
与FOO_C
,其他值被初始化为其默认值。
这是您将如何使用它:
int main() {
Foo testA = Builder<FooType::FOO_A>().a(12.5).build();
Foo testB = Builder<FooType::FOO_B>().b(10).build();
Foo testC = Builder<FooType::FOO_C>().c('x').build();
return 0;
}
对于构建器模式而言,这是一个很小的示例,但是从您的示例中看来,您正在使用更多的参数。 要以格式Builder& typeName(Type val) { _typeName = val; return *this; }
Builder& typeName(Type val) { _typeName = val; return *this; }
Builder& typeName(Type val) { _typeName = val; return *this; }
(它应该返回自我引用,以便可以链接这些功能)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.