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); return m; } template <int N> std::list<Base*> menu() { using Tuple = typename obtainRange<Database, N>::type; return menu<N, Tuple>(std::make_index_sequence<std::tuple_size<Tuple>::value>{}); }
Demo
If you cannot use C ++ 14 index_sequence , the following is an alternative implementation of C ++ 11-compatibile:
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 and make it work with arbitrary templates similar to Data and Map , for example. a std::tuple (instead of Data ) 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