Reputation: 5280
I hope to get a compile-time array, so come to this answer. Below is codes from the answer:
#include <array>
#include <algorithm>
#include <iterator>
#include <iostream>
template<int ...>
struct seq { };
template<int N, int ...S>
struct gens : gens<N-1, N-1, S...> { };
template<int ...S>
struct gens<0, S...> {
typedef seq<S...> type;
};
constexpr int f(int n) {
return n;
}
template <int N>
class array_thinger {
typedef typename gens<N>::type list;
template <int ...S>
static constexpr std::array<int,N> make_arr(seq<S...>) {
return std::array<int,N>{{f(S)...}};
}
public:
static constexpr std::array<int,N> arr = make_arr(list());
};
template <int N>
constexpr std::array<int,N> array_thinger<N>::arr;
int main() {
std::copy(begin(array_thinger<10>::arr), end(array_thinger<10>::arr),
std::ostream_iterator<int>(std::cout, "\n"));
}
But I am a newbie for metaprogramming, so here are two questions:
struct gens : gens<N-1, N-1, S...>
? It seems like Delegating constructors
in c++0x, but I'm not sure. struct seq
and typedef seq<S...> type
? Ahh, I also have no good command of template. Upvotes: 0
Views: 64
Reputation: 25663
What you have is a template which calls it self in recursive way.
If you write:
gens<3>::type
it uses your template
template<int N, int ...S>
struct gens : gens<N-1, N-1, S...> { };
For that N becomes 3 and the parameters in S are none. The template struct itself derives from gens<N-1, N-1, S...>
which then becomes here gens<2,2>
. This will again call ( recursive! ) itself.
So the gens template is called with N=2 and S is a list with one element which contains one int : 2. That again calls gens
, now with `gens<1,1,2>.
That repeat until N becomes 0. Now, because of the specialization of gens:
template<int ...S>
struct gens<0, S...> {
typedef seq<S...> type;
};
this specialization will be called. So here we get gens<0,0,1,2>. So N is 0 and S is a list of 0,1,2. Now the template generate the type type
. Type is now seq< 0,1,2>.
As gens derives recursive from itself, you can get type from that sequence of inheritance, because the specialization for 0 is the root of the struct.
So you can write:
gens<3>::type
which is: seq<0,1,2>
Upvotes: 1