Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;模板化类构造函数_C++ - Fatal编程技术网

C++ c++;模板化类构造函数

C++ c++;模板化类构造函数,c++,C++,我有一个类,它的构造函数接受了很多参数 enum class FooType {FOO_A, FOO_B, FOO_C}; class Foo { Foo(const double a, const double b, .... const double n); } 根据“类型”,我只需要参数的某个子集。目前有各种各样的构造函数具有不同数量的输入,但是将添加一些新类型,以便输入的数量相同。我可以将类型添加到构造函数中,在其中有一个长开关,但参数列表相当长 Foo(FooType ty

我有一个类,它的构造函数接受了很多参数

enum class FooType {FOO_A, FOO_B, FOO_C};

class Foo {
    Foo(const double a, const double b, .... const double n);
}
根据“类型”,我只需要参数的某个子集。目前有各种各样的构造函数具有不同数量的输入,但是将添加一些新类型,以便输入的数量相同。我可以将类型添加到构造函数中,在其中有一个长开关,但参数列表相当长

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);
std::使_共享(a、b、c);

注意:我不想使用继承,因为类的其余功能完全没有使用/需要它。

这可能是命名参数习惯用法的一个用例:

这将允许构造函数调用如下所示:

File f = OpenFile("foo.txt")
           .readonly()
           .createIfNotExist()
           .appendWhenWriting()
           .blockSize(1024)
           .unbuffered()
           .exclusiveAccess();
与上面的示例不同,您可以有一个包含所有命名参数的helper类,并且您的类构造函数将parameters类的实例作为其参数


这使您可以自由选择在构造时初始化的参数集。如果您想强制为不同类型初始化不同的子集,那么您应该只编写不同的构造函数版本。

这可能是命名参数习惯用法的一个用例:

这将允许构造函数调用如下所示:

File f = OpenFile("foo.txt")
           .readonly()
           .createIfNotExist()
           .appendWhenWriting()
           .blockSize(1024)
           .unbuffered()
           .exclusiveAccess();
与上面的示例不同,您可以有一个包含所有命名参数的helper类,并且您的类构造函数将parameters类的实例作为其参数


这使您可以自由选择在构造时初始化的参数集。如果您想强制为不同类型初始化不同的子集,那么您应该只编写不同的构造函数版本。

以下是如何使用生成器模式创建模板化构造函数:

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&typeName(Type val){{u typeName=val;return*this;}
的形式向任何生成器专门化添加另一个参数(它应该返回自引用,以便可以链接这些函数)。

以下是使用生成器模式创建模板化构造函数的方法:

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&typeName(Type val){u typeName=val;return*this;}
的形式向任何生成器专门化添加另一个参数(它应该返回自引用,以便可以链接这些函数)。

那么使用不同的构造函数有什么错?如果您必须在析构函数中执行反分配和其他清理,但是不同的类型需要不同的东西,您将如何进行(您是否将有一个成员变量来存储该类型?)似乎如果它们确实需要这么多不同的参数,那么它们应该被拆分为不同的类。代码中有某种工厂模式,比如createClassBasedOnType(类型t){switch(t){案例A:新对象类型A;案例B:新对象类型B;等等;注意:这不是继承,只是不同的类来反模块化。@Omid。新类型的构造函数需要与现有类型相同数量的参数(而且都是双倍的)所以签名应该是相同的。我基本上覆盖了一些默认参数。我猜传递一个包含所有成员的结构仍然是最简单的方法。我最好奇的是还有什么其他选项请注意模板参数到构造函数(或转换运算符)必须推导模板:
Foo
为类模板
Foo
提供了一个模板参数。使用不同的构造函数有什么不对?如果必须在析构函数中执行反分配和其他清理,但不同的类型需要不同的操作,您会怎么做(你会有一个成员变量来存储类型吗?)看起来如果他们真的需要这么多不同的参数,他们应该被分成不同的类。在你的代码中有一些工厂模式,比如createClassBasedOnType(类型t){switch(t){案例A:新对象类型A;案例B:新对象类型B;等等;;注意:这不是继承,只是不同的类来反模块化事物。@Omid。新类型的构造函数需要与现有类型相同数量的参数(并且都是双倍的)所以签名应该是相同的。我基本上覆盖了一些默认参数。我猜传递一个包含所有成员的结构是最简单的方法。我很好奇还有什么其他选项。注意模板参数是构造函数(或转换运算符)模板必须推导:
Foo
为类模板
Foo
提供了一个模板参数。啊,这实际上相当整洁。为我的案例编写成员函数似乎有点过火,但我非常喜欢这个想法,并且可能会在某个时候遇到这样的情况:这是一种优雅的方式,可以更好地理解这个想法,因为这将是一个构建在我看来,r模式。我将用它来写一个解决方案。啊,这实际上很好。为我的案例编写成员函数似乎有点过火,但我非常喜欢这个想法,并且可能会在某个时候得到一个案例,在我看来,这是一种优雅的方式来获得更好的想法,因为这将是一个构建器模式。我将用它来写一个解决方案那个