Cukup jelas.
Pada dasarnya, katakan saya memiliki daftar jenis seperti:
using type_list_1 = type_list<int, somestructA>;
using type_list_2 = type_list<somestructB>;
using type_list_3 = type_list<double, short>;
Mereka bisa menjadi nomor variadic dari daftar jenis.
Bagaimana cara saya mendapatkan daftar produk Cartesian?
result = type_list<
type_list<int, somestructB, double>,
type_list<int, somestructB, short>,
type_list<somestructA, somestructB, double>,
type_list<somestructA, somestructB, short>
>;
Saya mencoba-coba tentang cara membuat produk Cartesian dua arah seperti yang diberikan di sini: Bagaimana cara membuat produk Cartesian dari daftar jenis? , tapi n jalan sepertinya tidak begitu sepele.
Untuk saat ini saya sedang mencoba ...
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{});
}
}
Saya hanya akan mengatakan bahwa mengingat betapa sulitnya untuk melakukannya dengan benar, gunakan saja dorongan seperti dalam jawaban oleh Barry. Sayangnya saya harus terjebak dengan pendekatan linting tangan karena menggunakan boost atau tidak adalah keputusan yang berasal dari tempat lain :(
cartesian_product
adalah daftar daftar tipe, dan pada setiap langkah rekursi Anda ingin menambahkan item ke setiap daftar tipe dalam. Masuk ke tingkat pengemasan kedua dari paket ini membutuhkan pengurangan ...