【问题标题】:Factory class with variadic template arguments for constructor [duplicate]工厂类与结构函数的variadic模板参数[复制]
【发布时间】:2014-03-15 23:10:54
【问题描述】:

我正在尝试设计一个工厂类,它允许我使用任意数量的构造函数参数封装任何类的构造(派生自同一个基类“Base”)。当前设计仅支持一个或零个构造函数参数:

class FactoryBase
{
public:
    FactoryBase(std::string id) : id_(id) {}
    virtual ~FactoryBase(){}
    virtual Base* create() const = 0;
    std::string getId() const { return id_; }
protected:
    std::string id_;
};

template<class T, typename A> //One argument
class Factory : public FactoryBase
{
public:
    Factory(std::string id, A arg) : FactoryBase(id), arg_(arg) {}
    Base* create() const { return new T(arg_); }
private:
    A arg_;
};

template<class T> //zero arguments/default ctor
class Factory<T,void> : public FactoryBase
{
public:
    Factory(std::string id) : FactoryBase(id) {}
    Base* create() const { return new T(); }
};

我可以为每个参数数量添加一个模板特化,但我想学习如何“正确”地做到这一点。

【问题讨论】:

  • 是的,无法将“variadric”修复为 variadic,这让我发疯了
  • 基类中的: FactoryBase(id) {}不应该是: id_(id)吗?
  • FactoryBase::id_ 在所有情况下都必须初始化,并且为了强制我将它的值作为 FactoryBase 构造函数参数,同时不为 FactoryBase 提供默认构造函数,因此所有派生类的构造函数都必须提供 ID 值。
  • 我的意思是,在基类中,您在初始化列表中递归地调用构造函数FactoryBase(id)。对我来说,这看起来像是无限递归。
  • 是的,你是对的。摘录不是来自原始程序,所以我在创建示例代码时犯了一个错误。现在应该修好了。

标签: c++ templates


【解决方案1】:

根据我在duplicate 中提供的信息,您需要将参数的类型存储在类型列表中。在 C++11 中,这将是 std::tuple。您的类模板应采用放置在此元组中的参数的参数包。

构造函数应该是带有参数包的模板构造函数,然后您将其转发给元组数据成员的构造函数。

编译时整数序列生成器可用于访问 create() 中元组的每个元素(请参阅副本中的确切代码)。

【讨论】:

  • 是否可以从构造函数参数中推断出Factory 类型?我希望能够执行以下操作:Factory&lt;SomeClass&gt; fac1("ID123","arg0", 1.56, 4); 而不是 Factory&lt;SomeClass,std::string,double,std::string&gt; fac2("ID123","arg0", 1.56, 4);
  • 当然像Factory&lt;SomeClass&gt; fac1 = makeFactory&lt;SomeClass&gt;("ID123","arg0", 1.56, 4); 这样的东西会起作用,但是一个合适的构造器会很整洁,而不是一些外部函数。
  • @user1062874 抱歉,为了让构造函数工作,必须事先知道类型。这是因为元组数据成员需要先指定类型,然后才能将参数转发到其构造函数。这就是为什么我建议创建一个从参数中推断类型的辅助函数。
猜你喜欢
  • 2016-09-12
  • 1970-01-01
  • 2017-09-13
  • 1970-01-01
  • 2011-05-24
  • 2015-06-17
  • 2015-08-04
  • 2021-02-07
  • 2016-06-30
相关资源
最近更新 更多