Autoesplicativo.
Fondamentalmente, dire che ho elenchi di tipi in questo modo:
using type_list_1 = type_list<int, somestructA>;
using type_list_2 = type_list<somestructB>;
using type_list_3 = type_list<double, short>;
Possono essere un numero variabile di elenchi di tipi.
Come posso ottenere una lista dei tipi di prodotti cartesiani?
result = type_list<
type_list<int, somestructB, double>,
type_list<int, somestructB, short>,
type_list<somestructA, somestructB, double>,
type_list<somestructA, somestructB, short>
>;
Mi sono dilettato su come creare un prodotto cartesiano a due vie come indicato qui: Come creare il prodotto cartesiano di un elenco di tipi? , ma in nessun modo sembra essere così banale.
Per ora ci sto provando ...
template <typename...> struct type_list{};
// To concatenate
template <typename... Ts, typename... Us>
constexpr auto operator|(type_list<Ts...>, type_list<Us...>) {
return type_list{Ts{}..., Us{}...};
}
template <typename T, typename... Ts, typename... Us>
constexpr auto cross_product_two(type_list<T, Ts...>, type_list<Us...>) {
return (type_list<type_list<T,Us>...>{} | ... | type_list<type_list<Ts, Us>...>{});
}
template <typename T, typename U, typename... Ts>
constexpr auto cross_product_impl() {
if constexpr(sizeof...(Ts) >0) {
return cross_product_impl<decltype(cross_product_two(T{}, U{})), Ts...>();
} else {
return cross_product_two(T{}, U{});
}
}
Dirò solo che considerando quanto sia difficile farlo nel modo giusto, basta usare boost come nella risposta di Barry. Sfortunatamente devo essere bloccato con un approccio orientato alla mano perché usare boost o no è una decisione che viene da qualche altra parte :(
cartesian_product
è un elenco di elenchi di tipi e ad ogni fase di ricorsione si desidera aggiungere elementi a ciascun elenco di tipi interno. Arrivare a quel secondo livello di imballaggio richiede un po 'di detrazione ...