STL: std::integer_sequence

原理其实很简单就是二叉递归:

                                              6
                                            /
                                           /
                                         3
                                        /  \
                                       1    2
                                      /   /   \
                                type(0)  1     1
                                         |     |
                                      type(0) type(0)

 

template<size_t... _Indexes> struct _Index_tuple { };



template<size_t... _Indexes> struct _Index_tuple { };

  // Concatenates two _Index_tuples.
  template<typename _Itup1, typename _Itup2> struct _Itup_cat;

  template<size_t... _Ind1, size_t... _Ind2>
    struct _Itup_cat<_Index_tuple<_Ind1...>, _Index_tuple<_Ind2...>>
    {
      using __type = _Index_tuple<_Ind1..., (_Ind2 + sizeof...(_Ind1))...>;
    };

  // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
  template<size_t _Num>
    struct _Build_index_tuple
    : _Itup_cat<typename _Build_index_tuple<_Num / 2>::__type,
		typename _Build_index_tuple<_Num - _Num / 2>::__type>
    { };



  template<>
    struct _Build_index_tuple<1>
    {
      typedef _Index_tuple<0> __type;
    };

  template<>
    struct _Build_index_tuple<0>
    {
      typedef _Index_tuple<> __type;
    };

  /// Class template integer_sequence
  template<typename _Tp, _Tp... _Idx>
    struct integer_sequence
    {
      typedef _Tp value_type;
      static constexpr size_t size() { return sizeof...(_Idx); }
    };

  template<typename _Tp, _Tp _Num,
	   typename _ISeq = typename _Build_index_tuple<_Num>::__type>
    struct _Make_integer_sequence;

  template<typename _Tp, _Tp _Num,  size_t... _Idx>
    struct _Make_integer_sequence<_Tp, _Num, _Index_tuple<_Idx...>>
    {
      static_assert( _Num >= 0,
		     "Cannot make integer sequence of negative length" );

      typedef integer_sequence<_Tp, static_cast<_Tp>(_Idx)...> __type;
    };

  /// Alias template make_integer_sequence
  template<typename _Tp, _Tp _Num>
    using make_integer_sequence
      = typename _Make_integer_sequence<_Tp, _Num>::__type;

  /// Alias template index_sequence
  template<size_t... _Idx>
    using index_sequence = integer_sequence<size_t, _Idx...>;

  /// Alias template make_index_sequence
  template<size_t _Num>
    using make_index_sequence = make_integer_sequence<size_t, _Num>;

  /// Alias template index_sequence_for
  template<typename... _Types>
    using index_sequence_for = make_index_sequence<sizeof...(_Types)>;

 

demo:

#include <iostream>
#include <utility>
#include <tuple>
#include <array>
#include <typeinfo>



namespace impl{

template<typename Array, std::size_t... Indeices>
auto array_to_tuple_impl(const Array& array, std::index_sequence<Indeices...>)->decltype(std::make_tuple(array[Indeices]...))
{
    return std::make_tuple(array[Indeices]...);
//    return tuple;
}

}


template<typename Ty, std::size_t N, typename Indeices = std::make_index_sequence<N>>
auto array_to_tuple(const std::array<Ty, N>& array)->decltype(impl::array_to_tuple_impl(array, Indeices{}))
{
//    auto tuple = impl::array_to_tuple_impl(array, Indeices{});

    return /*tuple;*/ impl::array_to_tuple_impl(array, Indeices{});
}


struct Test
{
    int number{10};
};


void func(Test t);


int main()
{
    std::array<std::size_t, 3> array{1, 2, 3};
    auto tuple = array_to_tuple(array);


    int a  = Test{}.number;
    std::cout << a << std::endl;


    std::cout << typeid(decltype(func(Test{}))).name() << std::endl;


    return 0;
}

 

转载于:https://my.oschina.net/SHIHUAMarryMe/blog/1504246

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值