When working with non-default constructible types in C , initializing an std::array can be challenging, especially when the array size is determined by a template parameter.
To address this, we introduce a sophisticated approach that leverages sequence-type and generator concepts:
We define a sequence-type called seq using a template metafunction, which represents a sequence of sequential integers.
<code class="cpp">template<int ... N> struct seq { using type = seq<N...>; static const std::size_t size = sizeof ... (N); template<int I> struct push_back : seq<N..., I> {}; };</code>
Using this sequence, we construct a generator genseq that generates sequences of increasing length:
<code class="cpp">template<int N> struct genseq : genseq<N-1>::type::template push_back<N-1> {}; template<> struct genseq<0> : seq<> {}; template<int N> using genseq_t = typename genseq<N>::type;</code>
With the sequence in place, we define a repeat() function to create arrays initialized with the same value:
<code class="cpp">template<typename T, int...N> auto repeat(T value, seq<N...>) -> std::array<T, sizeof...(N)> { //unpack N, repeating `value` sizeof...(N) times //note that (X, value) evaluates to value return {(N, value)...}; }</code>
To initialize an std::array of non-default constructible type, we simply call repeat() with the desired value and the sequence generated by genseq_t
<code class="cpp">template<typename T, int N> void f(T value) { //genseq_t<N> is seq<0,1,...N-1> std::array<T, N>> items = repeat(value, genseq_t<N>{}); }</code>
This solution ensures elegant and efficient initialization of std::array, effectively eliminating the need for cumbersome manual repetition when n is a large template parameter.
The above is the detailed content of How to Initialize Non-Default Constructible std::array Elegantly with Template Metaprogramming?. For more information, please follow other related articles on the PHP Chinese website!