Explicite.
Fondamentalement, disons que j'ai des listes de types comme ceci:
using type_list_1 = type_list<int, somestructA>;
using type_list_2 = type_list<somestructB>;
using type_list_3 = type_list<double, short>;
Ils peuvent être des nombres variés de listes de types.
Comment obtenir une liste de types de produits cartésiens?
result = type_list<
type_list<int, somestructB, double>,
type_list<int, somestructB, short>,
type_list<somestructA, somestructB, double>,
type_list<somestructA, somestructB, short>
>;
J'ai essayé de créer un produit cartésien bidirectionnel comme indiqué ici: Comment créer le produit cartésien d'une liste de types? , mais rien ne semble être si insignifiant.
Pour l'instant j'essaye ...
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{});
}
}
Je dirai simplement que compte tenu de la difficulté de bien faire les choses, utilisez simplement boost comme dans la réponse de Barry. Malheureusement, je dois être bloqué avec une approche roulée à la main car utiliser boost ou non est une décision qui vient d'ailleurs :(
cartesian_product
s'agit d'une liste de listes de types, et à chaque étape de récursivité, vous voulez ajouter des éléments à chaque liste de types interne. Entrer dans ce deuxième niveau d'emballage prend une certaine déduction ...