原理其实很简单就是二叉递归:
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;
}