c++ - 用模板参数填充容器

标签 c++ templates c++11 variadic

我想将传递给可变参数模板的模板参数填充到一个固定长度的数组中。为此,我编写了以下辅助函数模板

template<typename ForwardIterator, typename T>
void fill(ForwardIterator i) { }

template<typename ForwardIterator, typename T, T head, T... tail>
void fill(ForwardIterator i) {
  *i = head;
  fill<ForwardIterator, T, tail...>(++i);
}

下面的类模板

template<typename T, T... args>
struct params_to_array;

template<typename T, T last>
struct params_to_array<T, last> {
  static const std::size_t SIZE = 1;
  typedef std::array<T, SIZE> array_type;

  static const array_type params;

private:
  void init_params() {
    array_type result;
    fill<typename array_type::iterator, T, head, tail...>(result.begin());
    return result;
  }
};

template<typename T, T head, T... tail>
struct params_to_array<T, head, tail...> {
  static const std::size_t SIZE = params_to_array<T, tail...>::SIZE + 1;
  typedef std::array<T, SIZE> array_type;

  static const array_type params;

private:
  void init_params() {
    array_type result;
    fill<typename array_type::iterator, T, last>(result.begin());
    return result;
  }
};

并通过

初始化静态常量
template<typename T, T last>
const typename param_to_array<T, last>::array_type
param_to_array<T, last>::params =
  param_to_array<T, last>::init_params();

template<typename T, T head, T... tail>
const typename param_to_array<T, head, tail...>::array_type
param_to_array<T, head, tail...>::params =
  param_to_array<T, head, tail...>::init_params();

现在是数组

param_to_array<int, 1, 3, 4>::params

std::array<int, 3>并包含值 1 , 34 .我认为必须有一种更简单的方法来实现这种行为。有什么建议吗?

编辑:正如 Noah Roberts 在他的回答中所建议的那样,我修改了我的程序,如下所示:我编写了一个新结构来计算参数列表中的元素:

template<typename T, T... args>
struct count;

template<typename T, T head, T... tail>
struct count<T, head, tail...> {
  static const std::size_t value = count<T, tail...>::value + 1;
};

template<typename T, T last>
stuct count<T, last> {
  static const std::size_t value = 1;
};

并编写了以下函数

template<typename T, T... args>
std::array<T, count<T, args...>::value>
params_to_array() {
  std::array<T, count<T, args...>::value> result;
  fill<typename std::array<T, count<T, args...>::value>::iterator,
       T, args...>(result.begin());
  return result;
}

现在我得到了

params_to_array<int, 10, 20, 30>()

一个std::array<int, 3>内容10 , 2030 .还有什么建议吗?

最佳答案

无需手动计算参数包中的类型数量,这就是 sizeof... 运算符的用途。此外,我将使 fill() 的迭代器类型可推导,无需明确指定它:

template<typename T, typename FwdIt>
void fill(FwdIt it) { }

template<typename T, T head, T... tail, typename FwdIt>
void fill(FwdIt it) {
    *it = head;
    fill<T, tail...>(++it);
}

template<class T, T... args> 
std::array<T, sizeof...(args)> params_to_array() {
    std::array<T, sizeof...(args)> a;
    fill<T, args...>(a.begin());
    return a;
};

然而,参数包在初始化列表上下文中也是可扩展的,这使得 fill() 变得多余:

template<class T, T... args> 
std::array<T, sizeof...(args)> params_to_array() {
    std::array<T, sizeof...(args)> a = {{args...}};
    return a;
};

关于c++ - 用模板参数填充容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2850646/

相关文章:

c++ - 如何向 C++ 应用程序添加反射?

c++ - 一个模板化的 'strdup()' ?

c++ - 在构造函数中转换 void* 并访问值

javascript - Backbone.js:将事件绑定(bind)到模板按钮

c++ - 模板推导失败

c++ - libc++ 中的 `__gnu_cxx::temporary_buffer`?

c++ - 将一系列值映射到单个值

c++ - 我似乎无法使用 enable_if 实例化类特化

c++ - 我的递归斐波那契程序有什么问题?

c++ - Qt - 图形用户界面卡住