Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Luc's solution is clean and straightforward, but sorely lacks fun.<br> Because there is only one proper way to use variadic templates and it is to abuse them to do crazy overcomplicated metaprogramming stuff :)</p> <p>Like this :</p> <pre><code>template &lt;class T, size_t... Indx, class... Ts&gt; std::array&lt;T, sizeof...(Indx)&gt; split_array_range_imp(pack_indices&lt;Indx...&gt; pi, Ts... ts) { return std::array&lt;T, sizeof...(Indx)&gt;{get&lt;Indx&gt;(ts...)...}; //TADA } template &lt;class T, size_t begin, size_t end, class... Ts&gt; std::array&lt;T, end - begin&gt; split_array_range(Ts... ts) { typename make_pack_indices&lt;end, begin&gt;::type indices; return split_array_range_imp&lt;T&gt;(indices, ts...); } template &lt;size_t N&gt; struct DoubleArray { std::array &lt;int, N&gt; p, q; template &lt;typename ... Ts&gt; DoubleArray (Ts ... ts) : p( split_array_range&lt;int, 0 , sizeof...(Ts) / 2 &gt;(ts...) ), q( split_array_range&lt;int, sizeof...(Ts) / 2, sizeof...(Ts) &gt;(ts...) ) { } }; int main() { DoubleArray&lt;3&gt; mya{1, 2, 3, 4, 5, 6}; std::cout &lt;&lt; mya.p[0] &lt;&lt; "\n" &lt;&lt; mya.p[1] &lt;&lt; "\n" &lt;&lt; mya.p[2] &lt;&lt; std::endl; std::cout &lt;&lt; mya.q[0] &lt;&lt; "\n" &lt;&lt; mya.q[1] &lt;&lt; "\n" &lt;&lt; mya.q[2] &lt;&lt; std::endl; } </code></pre> <p>It is quite short, except that we need to code some helper :</p> <p>First we need the structure make_pack_indices, which is used to generate a range of integer at compile-time. For example <code>make_pack_indices&lt;5, 0&gt;::type</code> is actually the type <code>pack_indices&lt;0, 1, 2, 3, 4&gt;</code></p> <pre><code>template &lt;size_t...&gt; struct pack_indices {}; template &lt;size_t Sp, class IntPack, size_t Ep&gt; struct make_indices_imp; template &lt;size_t Sp, size_t ... Indices, size_t Ep&gt; struct make_indices_imp&lt;Sp, pack_indices&lt;Indices...&gt;, Ep&gt; { typedef typename make_indices_imp&lt;Sp+1, pack_indices&lt;Indices..., Sp&gt;, Ep&gt;::type type; }; template &lt;size_t Ep, size_t ... Indices&gt; struct make_indices_imp&lt;Ep, pack_indices&lt;Indices...&gt;, Ep&gt; { typedef pack_indices&lt;Indices...&gt; type; }; template &lt;size_t Ep, size_t Sp = 0&gt; struct make_pack_indices { static_assert(Sp &lt;= Ep, "__make_tuple_indices input error"); typedef typename make_indices_imp&lt;Sp, pack_indices&lt;&gt;, Ep&gt;::type type; }; </code></pre> <p>We also need a get() function, very similar to std::get for tuple, such as <code>std::get&lt;N&gt;(ts...)</code> return the Nth element of a parameters pack.</p> <pre><code>template &lt;class R, size_t Ip, size_t Ij, class... Tp&gt; struct Get_impl { static R&amp; dispatch(Tp...); }; template&lt;class R, size_t Ip, size_t Jp, class Head, class... Tp&gt; struct Get_impl&lt;R, Ip, Jp, Head, Tp...&gt; { static R&amp; dispatch(Head&amp; h, Tp&amp;... tps) { return Get_impl&lt;R, Ip, Jp + 1, Tp...&gt;::dispatch(tps...); } }; template&lt;size_t Ip, class Head, class... Tp&gt; struct Get_impl&lt;Head, Ip, Ip, Head, Tp...&gt; { static Head&amp; dispatch(Head&amp; h, Tp&amp;... tps) { return h; } }; template &lt;size_t Ip, class ... Tp&gt; typename pack_element&lt;Ip, Tp...&gt;::type&amp; get(Tp&amp;... tps) { return Get_impl&lt;typename pack_element&lt;Ip, Tp...&gt;::type, Ip, 0, Tp...&gt;::dispatch(tps...); } </code></pre> <p>But to build get() we also need a pack_element helper structure, again very similar to std::tuple_element, such as <code>pack_element&lt;N, Ts...&gt;::type</code> is the Nth type of the parameters pack.</p> <pre><code>template &lt;size_t _Ip, class _Tp&gt; class pack_element_imp; template &lt;class ..._Tp&gt; struct pack_types {}; template &lt;size_t Ip&gt; class pack_element_imp&lt;Ip, pack_types&lt;&gt; &gt; { public: static_assert(Ip == 0, "tuple_element index out of range"); static_assert(Ip != 0, "tuple_element index out of range"); }; template &lt;class Hp, class ...Tp&gt; class pack_element_imp&lt;0, pack_types&lt;Hp, Tp...&gt; &gt; { public: typedef Hp type; }; template &lt;size_t Ip, class Hp, class ...Tp&gt; class pack_element_imp&lt;Ip, pack_types&lt;Hp, Tp...&gt; &gt; { public: typedef typename pack_element_imp&lt;Ip-1, pack_types&lt;Tp...&gt; &gt;::type type; }; template &lt;size_t Ip, class ...Tp&gt; class pack_element { public: typedef typename pack_element_imp&lt;Ip, pack_types&lt;Tp...&gt; &gt;::type type; }; </code></pre> <p>And here we go.<br> Actually I don't really understand why pack_element and get() are not in the standard library already. Those helpers are present for std::tuple, why not for parameters pack ?</p> <p>Note : My implementation of pack_element and make_pack_indices is a direct transposition of std::tuple_element and __make_tuple_indices implementation found in libc++.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload