0

我有一些Builder构建Object. 我计划Object用策略对象替换一些 的胆量,例如能够设置一些容器类型Storage。具体来说,我想使用Builder来设置 的策略对象,Object如果没有指定则回退到某个默认值;在我的头顶上,像这样:

class Builder {
public
    Builder();

    // ... builder methods

    template<typename S>
    Builder& storage() { Storage = S; }

    Object init() { return Object<Storage>(...); }

private:
    typedef std::vector Storage;
}

template<typename Storage>
class Object { ... }

Object o = Builder()
    .storage<std::list>()
    .init()

问题的症结在于:我可以使用 typedef 作为一种“模板变量”,以便存储用户定义的模板变量吗?

为了提供更多上下文,Builder必须支持从 json 配置文件创建相当复杂Object的文件,将每个键及其验证委托给单个方法。我有一个静态命名构造函数Builder::from_config(...)和一个Builder::load_config(...)为我做这件事的方法,但我想支持从配置文件中选择策略对象。否则,我只需将模板添加到Builder::init()方法中就可以了,这样我就可以将我的策略对象传递给Object.

4

2 回答 2

1

我不明白你到底想要什么,但是......

问题的症结在于:我可以使用 typedef 作为一种“模板变量”,以便存储用户定义的模板变量吗?

我不这么认为;类型可以是模板参数,而不是变量;所以 typedef 是一个固定的实体,(据我所知)不能改变。

而且:

typedef std::vector Storage;

不起作用,因为std::vector<int>它是一种类型,但std::vector不是。

std::vector可以是模板模板参数。

为了帮助您,我能想到的最好的方法是Storage带有模板模板参数的内部模板结构。

下面是一个可编译的例子

#include <list>

template <template <typename ...> class C>
class Object
 { };

class Builder 
 {
   private:
      template <template <typename...> class C>
      struct Storage
       { Object<C> init() { return Object<C>{}; } };

   public:
      Builder ()
       { }

      template <template <typename...> class C>
      Storage<C> & storage() { static Storage<C> ret{}; return ret; }
 };

int main ()
 {
   auto o = Builder{}.storage<std::list>().init();

   static_assert(std::is_same<decltype(o), Object<std::list>>{}, "!");
 }
于 2017-07-15T19:00:46.527 回答
0

为什么不只是

template <template<class...> class StorageT>
class Builder
{
     // ...
    StorageT<Object> storage_;
};

Builder<std::vector>()...;
Builder<std::list>()...;
于 2017-07-15T18:53:09.363 回答