简体   繁体   English

用模板参数填充容器

[英]Fill container with template parameters

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

the following class template 以下课程模板

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

and initialized the static constants via 并通过初始化静态常量

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

and

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

Now the array 现在数组

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

is a std::array<int, 3> and contains the values 1 , 3 and 4 . 是一个std::array<int, 3>和包含值134 I think there must be a simpler way to achieve this behavior. 我认为必须有一种更简单的方法来实现此行为。 Any suggestions? 有什么建议么?

Edit: 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: 编辑:正如诺亚·罗伯茨(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;
};

and wrote the following function 并写了以下函数

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

Now I get with 现在我有了

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

a std::array<int, 3> with the content 10 , 20 and 30 . 一个std::array<int, 3>与内容102030 Any further suggestions? 还有其他建议吗?

There is no need to count the number of types in a parameter pack manually, thats what the sizeof... operator is for. 无需手动计算参数包中类型的数量,这就是sizeof...运算符的用途。 Additionally i'd make the iterator type for fill() deducible, there is no need to specify it explicitly: 另外,我将使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;
};

Parameter packs however are also expandable in initializer-list contexts, which makes fill() redundant: 但是,参数包在初始化列表上下文中也可以扩展,这使fill()变得多余:

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

The only reason I can see for a specialization for terminus in param_to_array is this line: 我可以看到在param_to_array中对终端进行专业化处理的唯一原因是:

static const std::size_t SIZE = params_to_array<T, tail...>::SIZE + 1;

Since your params_to_array metafunction creates the array though you're going to end up instantiating arrays of size N, N-1, ...., 1. Thus I think your object could use some help from composition and the single responsibility rule. 由于您的params_to_array元函数将创建数组,尽管您最终将实例化大小为N,N-1,....,1的数组。因此,我认为您的对象可以利用组合和单一职责规则提供一些帮助。 Create another metafunction that can count the elements in a parameter list and use it instead of this method. 创建另一个可以对参数列表中的元素进行计数的元函数,并使用它代替此方法。 Then you can get rid of this recursion in params_to_array at the least. 然后,您至少可以摆脱params_to_array中的这种递归。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 STL容器上的模板模板参数 - template template parameters on STL container 容器模板参数性能对比? - Performance comparison about template parameters of container? 具有多个模板参数的模板容器与具有不同模板参数的其他模板容器交互 - Template container with multiple template parameters interacting with other template containers with a different template parameter 如何在容器和类型均为参数的情况下创建模板函数? - How create template functions where both the container and the type are parameters? 转换一个class包装容器使用模板参数进行分配 - Convert a class wrapping a container to use template parameters for allocation 为什么 STL 容器适配器需要值和容器类型作为模板参数? - Why do STL container adapters require both value and container type as template parameters? 为什么 C++ 标准容器迭代器会忽略其底层容器的一些模板参数? - Why do C++ std container iterators ignore some template parameters of their underlying container? 包含类定义的模板容器,只需要多个模板参数之一 - Template container with contained class definition that only needs one of multiple template parameters 带有容器和默认分配器的模板模板参数:我可以使我的声明更紧凑吗? - template template parameters with container and default allocator: can I make my declaration more compact? 使用模板参数作为模板参数 - Using template parameters as template parameters
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM