用模板参数填充容器 [英] Fill container with template parameters

查看:88
本文介绍了用模板参数填充容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to fill the template parameters passed to a variadic template into an array with fixed length. For that purpose I wrote the following helper function templates

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 并包含值 1 code>和 4 。我认为必须有一个更简单的方法来实现这种行为。任何建议?

is a std::array<int, 3> and contains the values 1, 3 and 4. I think there must be a simpler way to achieve this behavior. Any suggestions?

编辑:正如Noah Roberts在他的回答中建议的,我修改了我的程序,在参数列表中:

As Noah Roberts suggested in his answer I modified my program like the following: I wrote a new struct counting the elements in a parameter list:

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>()

a std :: array< int,3> with the content 10 20 30 。任何进一步的建议?

a std::array<int, 3> with the content 10, 20 and 30. Any further suggestions?

推荐答案

没有必要手动计算参数包中的类型数, c $ c> sizeof ... 运算符。另外,我会使迭代器类型为 fill() deducible,没有必要明确指定:

There is no need to count the number of types in a parameter pack manually, thats what the sizeof... operator is for. Additionally i'd make the iterator type for fill() deducible, there is no need to specify it explicitly:

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;
};

但是参数包也可以在初始化器列表上下文中扩展,这使得填充() redundant:

Parameter packs however are also expandable in initializer-list contexts, which makes fill() redundant:

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

这篇关于用模板参数填充容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆