c++ - How to return a template pack nested in other pack? -
c++ - How to return a template pack nested in other pack? -
the next code works:
#include <iostream> #include <list> struct base of operations {}; struct : base of operations {}; struct b : base of operations {}; struct c : base of operations {}; struct d : base of operations {}; struct e : base of operations {}; struct f : base of operations {}; template <int key, typename... range> struct map {}; // one-to-many map (mapping key range...) template <typename...> struct info {}; using database = data< map<0, a,b,c>, map<1, d,e,f> >; template <int n, typename first, typename... rest> // n has meaning in program, not shown here. void insertinmenu (std::list<base*>& menu) { menu.push_back(new first); insertinmenu<n, rest...> (menu); } template <int n> void insertinmenu (std::list<base*>&) {} // end of recursion. template <int n> std::list<base*> menu() { std::list<base*> m; insertinmenu<0, a,b,c>(m); // a,b,c should obtained using n , database. homecoming m; } int main() { std::list<base*> m = menu<0>(); std::cout << "m.size() = " << m.size() << std::endl; // 3 }
but indicated in comment above, want utilize database
, value n
obtain range a,b,c
(or d,e,f
) or whatever. don't know how that? can help? line
insertinmenu<0, a,b,c>(m);
needs replaced like
obtainrange<database, n>()
since compile-time known values should plenty info obtain range want.
obtainrange<database, 0>()
should homecoming a,b,c
and
obtainrange<database, 1>()
should homecoming d,e,f
in case.
template <typename d, int n> struct obtainrange; template <int n, typename... ts, typename... maps> struct obtainrange<data<map<n, ts...>, maps...>, n> { using type = std::tuple<ts...>; }; template <int n, int m, typename... ts, typename... maps> struct obtainrange<data<map<m, ts...>, maps...>, n> : obtainrange<data<maps...>, n> {}; template <int n, typename tuple, std::size_t... is> std::list<base*> menu(std::index_sequence<is...>) { std::list<base*> m; insertinmenu<0, typename std::tuple_element<is, tuple>::type...>(m); homecoming m; } template <int n> std::list<base*> menu() { using tuple = typename obtainrange<database, n>::type; homecoming menu<n, tuple>(std::make_index_sequence<std::tuple_size<tuple>::value>{}); }
demo
if can't utilize c++14's index_sequence
, below alternative c++11-compatibile implementation:
template <std::size_t... is> struct index_sequence {}; template <std::size_t n, std::size_t... is> struct make_index_sequence_h : make_index_sequence_h<n - 1, n - 1, is...> {}; template <std::size_t... is> struct make_index_sequence_h<0, is...> { using type = index_sequence<is...>; }; template <std::size_t n> using make_index_sequence = typename make_index_sequence_h<n>::type;
you can go further, , create working arbitrary templates similar data
, map
, e.g. std::tuple
(instead of data
) of map
s, using template template-parameters:
template <typename d, int n> struct obtainrange; template <template <typename...> class db , template <int, typename...> class mp , typename... ts , typename... maps , int n> struct obtainrange<db<mp<n, ts...>, maps...>, n> { using type = std::tuple<ts...>; }; template <template <typename...> class db , template <int, typename...> class mp , typename... ts , typename... maps , int m , int n> struct obtainrange<db<mp<m, ts...>, maps...>, n> : obtainrange<db<maps...>, n> {};
demo 2
c++ templates c++11 variadic-templates pack
Comments
Post a Comment