为构造函数重用可变参数模板

时间:2017-08-25 17:28:21

标签: c++ c++11 generics constructor variadic-templates

如何存储可变参数模板以在以后的实例中重用?

代码示例:

.as-console-wrapper { max-height: 100% !important; top: 0; }

有没有什么办法可以将varidic模板存储为一个对象/集合,使你可以重用它,在这种情况下是构造函数?

我见过人们将参数存储在template <typename T, typename ...initArgs> Collection_class { std::vector<T> storage; initArgs ...constructorArguments; Collection_class<T, initArgs>(initArgs... args) { constuctorArguments = args; } void CreateInstance() { storage.emplace(constructorArguments); } } 中但是我不确定如何在泛型类中使用它。

非常感谢,JJ。

2 个答案:

答案 0 :(得分:2)

您可以通过将参数存储在元组中来实现此目的:

#include <vector>
#include <tuple>

template<typename T, int index, typename ...initArgs>
struct VectorInit {
  static void append(std::vector<T> & dst, 
                     std::tuple<initArgs...> const& args) {
    VectorInit<T, index-1, initArgs...>::append(dst, args);
    dst.emplace_back(std::get<index>(args));
  }
};

template<typename T, typename ...initArgs>
struct VectorInit<T, 0, initArgs...> {
  static void append(std::vector<T> & dst, 
                     std::tuple<initArgs...> const& args) {
    dst.emplace_back(std::get<0>(args));
  }
};

template <typename T, typename ...initArgs>
class Collection_class {
   std::vector<T> storage; 
   std::tuple<initArgs...> init_args;

public:
   Collection_class(initArgs... args)
     : init_args(args...) {
   }

   void CreateInstance() {
     storage.reserve(sizeof...(initArgs));
     VectorInit<T, sizeof...(initArgs)-1, initArgs...>::append(storage, init_args);
   }
};

int main() {
    Collection_class<double, float, int> test(1.2f, 4);
    test.CreateInstance();
}

编辑: CreateInstance()可以通过递归剥离元组的每个元素来实现。我是从sizeof...(args)到0完成的,这就是递归发生在emplace_back之前的原因。

使用参数包扩展可能有一种更简洁的方法,但这是一个简单的例子,我发现模板特化路由更简单。

答案 1 :(得分:0)

为什么不让std::vector处理:

template <typename T>
Collection_class {

   std::vector<T> storage; 
public:
   Collection_class<T>(std::initializer_list<T> initargs) : storage(initargs) {
   }
}

请注意,不再需要延期CreateInstance()

initArgs可变参数模板参数可让您的Collection_class实例化“爆炸”以获取任何可能的参数组合。那肯定不是你真正想要的。