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 :
- consider boost multidimensional array library.
- i not sure of final goal is, might overkill.
- as second edit, declaring
tuplemultiple vectors of different dimensions easy :
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
Post a Comment