The construction is done with recursive substitution:
make_int_pack<5> derives from append<typename make_int_pack<5-1>::type,5-1>.
But make_int_pack<5-1>::type is make_int_pack<4>::type.
But make_int_pack<4>::type is the definition from append<typename make_int_pack<4-1>::type,4-1>, and so on.
So make_int_pack<5> derives from
append<append<append<append<append<int_pack<>,0>,1>,2>,3>,4>
, which derives from int_pack<0,1,2,3,4>.
To use this int_pack we have to do something like pattern matching (c++11).
template<class T>struct test{};
template<size_t ... Is>
struct test<int_pack<Is...>>{
// use template parameter pack
};
We could then use the static members of test<make_int_pack<5>> as result of some compiletime compilation or complex type construction.
Another possible way is to have
template<size_t... Is>
size_t test_fun(int_pack<Is...>);
,which would be called like test_fun(make_int_pack<5>());
Edit:
I'm wondering why there's two append struct, what's the difference
between them?
You want to be able to write append<int_pack<0,1,2,3>,42>. Therefor append has to take two template parameters. That is your first declaration.
template<class T,size_t i> struct append{};
But actually you do not need the type int_pack<0,1,2,3> but the template paramter pack used. In c++ we have partial template specialization. If the type T happends to be an int_pack we use the special (second) declaration. In this way we can kind of pattern match the templated type T and get the template parameters used do define the int_pack.
template<size_t ... Is,size_t i>
struct append<int_pack<Is...>,i> : int_pack<Is...,i>{};
what's the meaning of append,0> ?
This will fall in the second case. We have an empty template parameter pack, since the brackets are empty int_pack<>. So we derive from int_pack<0> and therefor our append<int_pack<>,0>::type is int_pack<0>.
So in summary:
look at template parameter packs and partial template specialization.
When working with types it is basicly just substitution of expressions.
std::index_sequence/std::make_integer_sequence.