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

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

先来看make_array的实现:

 

template <typename D = void, typename... TList>

constexpr array_detail::return_type<D, TList...> make_array(TList&&... t) {

  using value_type =

      typename array_detail::return_type_helper<D, TList...>::type;

  return {{static_cast<value_type>(std::forward<TList>(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 <std::size_t Size, typename MakeItem>

constexpr auto make_array_with(MakeItem const& make) {

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

}

 

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

template <typename MakeItem, std::size_t... Index>

FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN constexpr auto make_array_with(

    MakeItem const& make,

    index_sequence<Index...>) {

      return std::array<decltype(make(0)), sizeof...(Index)>{{make(Index)...}};

}

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

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

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

 make_array_with( MakeItem const& make,

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

               return std::array<int,4>{{ 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的可变参数构造函数的调用。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农心语

您的鼓励是我写作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值