facebook folly库make_array的源码解析(下)

Folly 提供了make_array 和make_array_with的帮助模板类了初始化std::array数组。

先来看make_array的实现:

 

template

constexpr array_detail::return_type make_array(TList&&... t) {

  using value_type =

      typename array_detail::return_type_helper::type;

  return {{static_cast(std::forward(t))...}};

}

make_array的实现比较简单,首先声明一个value_type,它是通过return_type_helper对传入的实参进行类型推导来确定数组的元素类型。最后用{{…}}来将这些实参组合生成为intialize_list进行返回。

 

而return_type_helper利用std::common_type来确定传入的每个实参都可隐式转换的公共类型,看std::common_type的定义:

Determines the common type among all types T..., that is the type all T... can be implicitly converted to. If such a type exists (as determined according to the rules below), the member type names that type. Otherwise, there is no member type.

 

分析万make_array,那么再来分析make_array_with,它允许我们提供一个元素构造器(可调用对象,譬如仿函数,在c++17中可以是lambda函数)对array的元素在编译期进行设定。

 

以下主要分析一下make_array_with的实现过程:

 

先来看看make_array_with的定义

template

constexpr auto make_array_with(MakeItem const& make) {

  return array_detail::make_array_with(make, make_index_sequence{});

}

 

在这个定义中,make_array_with需要输入一个元素构造器可调用对象,并用一个模板参数Size来设置将要生成的数组的元素个数, 这个版本的make_array_with又委托给了另外一个版本的make_array_with模板函数,如下:

template

FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN constexpr auto make_array_with(

    MakeItem const& make,

    index_sequence) {

      return std::array{{make(Index)...}};

}

这个版本的make_array_with比较好理解,就是利用可变参数模板函数来生成一个用于array初始化的初始化列表,生成的数组的类型为make(0)的返回值对应的类型。

这里比较关键的是index_sequence,这里的Index… 在return std::array{{make(Index)...}}; 中被展开。

譬如,假设准备用make来生成类型为int包含4个元素的数组,那么展开后为:

 make_array_with( MakeItem const& make,

                index_sequence<0, 1, 2, 3 > ){

               return std::array{{ make(0),make(1),make(2),make(3)}};

             }

那么这个index_sequence是怎么生成出来的呢?

这就要归功于make_index_sequence了,make_index_sequence根据其唯一的模板参数N来创建一个0到N-1的整数序列。

我们来看看std:: make_index_sequence的定义:

The class template std::integer_sequence represents a compile-time sequence of integers. When used as an argument to a function template, the parameter pack Ints can be deduced and used in pack expansion.

这样子,最终将make_array_with转化为对array的可变参数构造函数的调用。

 

你可能感兴趣的:(c++开发)