c++ - c++11 variadic programming, how to define a tower of vectors -


how (if possible) can use c++11 variadic programming define series of vector's in function body, (or in other words, sequence of n-dimensional arrays decreasing n's until 0), variables below?

vector<vector<vector<int>>> v<3>; vector<vector<int>> v<2>; vector<int> v<1>; int v<0>; 

what imagined like:

#include <iostream> #include <vector> using namespace std;  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; };  template<int ...s> void f(seq<s...>) {   //how write definitions of v<n> here?   vector<vector<...(n layers)<vector<int> ...> v<n>;     //??how-to, not valid c++   vector<vector<...(n -1 layers)<vector<int> ...> v<n-1>;//??how-to, not valid c++   //...   vector<int> v<1>;  //??how-to, not valid c++   int v<0>;          //??how-to, not valid c++    //... }  int main() {   f(typename gens<3>);   return 0; } 

also, easier in c++14?

thanks,

--edit--

just clarify, mean "a tower of vectors" best described n-tuple (v_1, v_2, ..., v_n), n integral template parameter. v_1 of vector, v_2 of vector>, , on.

--edit2--

so far, quantdev , r's answers have solved problem of defining n-tuple fixed n, 3, cannot generate tuple unspecified n. in addition functionality in answers, need function can used gen_tower<n> returns tuple(v1,v2,...,vn).

consider example of using variadic programming compute factorials. need function compute factorial factorial<n>() n, in addition ability write out specific expression <1*2*3> manually. (that reason why asked variadic programming , whether c++14 make easier.)

p.s.

purely out of personal interests, want sequence implement generic function can read n-dimensional array file. don't know how yet, think @ step one, should able define final n-dimensional array, , intermediate k-dimensional arrays k n-1 1. can read 2-dimensional arrays, , 3-dimensionals. nice able read arrays of dimensions.

there no need variadics, recursive typedef sufficient generate types @ compile time.


how is implemented ?

1) provide template 2 arguments : vector elements type (t), , desired dimension of structure (size_t n). declare typedef type : based on declaration of type template instantiated depth n-1, hence recursion.

template<typename t, size_t n> struct vectorgenerator {     typedef std::vector< typename vectorgenerator<t, n-1>::type > type; }; 

2) provide termination case ending recursion, here specialization of our template dimension 0, declaring type of usual std::vector<t>.

template<typename t> struct vectorgenerator<t, 0> {     typedef std::vector<t> type; }; 

how use ?

we can declare vector v of type vectorgenerator<t, n>::type :

vectorgenerator<double, 4>::type v; // v depth of 4 , handle double 

but it's not readable or convenient, , pretty verbose. let's introduce new names our types.

this perfect case template aliasing, (c++11) using keyword aliasing. have 2 different ways of aliasing :

1) declare alias particular dimension , type, here call v3 n=3 , t=double :

using v3 = vectorgenerator<double, 3>::type;  // alias  v3 v;                                         // use alias 

or,

2) declare template alias particular type, leaving dimension template parameter:

template <size_t n>  using v = typename vectorgenerator<double, n>::type;  // alias  v<3> v;                                              // use alias 

final code sample:

template<typename t, size_t n> struct vectorgenerator {     typedef std::vector< typename vectorgenerator<t, n-1>::type > type; };  template<typename t> struct vectorgenerator<t, 0> {     typedef std::vector<t> type; };  // alias v3, v2 ... usage using v3 = vectorgenerator<double, 3>::type; using v2 = vectorgenerator<double, 2>::type;  // alias v <k> usage template <size_t n>  using v = typename vectorgenerator<double, n>::type;  int main() {      v<3> v3;     v<2> v2;     v3.push_back(v2);     return 0; } 

notes :

example:

auto tower = std::tuple<v<1>, v<2>, v<3>>(v1, v2, v3); 

for generic tuple generation of multiple "towers", @mpark gave a working c++14 solution, adapt here code sample:

template <typename t> struct identity { using type = t; };  // generate tuple of towers mapping index_sequence on gen_tower. template <typename t, std::size_t... is> std::tuple<vectorgenerator<t, is>...> gen_towers_impl(std::integer_sequence<is...>);  // make index_sequence n , use gen_towers_impl. template <typename t, std::size_t n> struct gen_towers     : identity<decltype(gen_towers_impl<t>(std::make_index_sequence<n>()))> {};  // convenience type aliases template <typename t, std::size_t n> using gen_towers_t = typename gen_towers<t, n>::type; 

you need -std=c++1y compile (and include <utility> , <tuple> headers)

see working example here.


Comments

Popular posts from this blog

javascript - RequestAnimationFrame not working when exiting fullscreen switching space on Safari -

jsf - How to ajax update an item in the footer of a PrimeFaces dataTable? -

jquery - Keeping Kendo Datepicker in min/max range -