I\'d like to create the cross product of a list of types using variadic templates.
Here\'s what I have so far:
#include
#include <
So far all solutions have drawbacks, unnecessary dependencies, unnecessary helpers and all are restricted to the Cartesian power of two. The following solution has no such drawbacks and supports:
It was actually to harder to implement (but good as homework) then I thought. I am actually thinking about creating a little generator which allows me an extended template syntax which makes these things really easy.
Simplified the code works as follows: product
converts an input list tuple
into tuple
. This second list is then passed to product_helper
which does the recursive Cartesian product computation.
template struct cat2;
template class R, typename... As, typename... Bs>
struct cat2 , R > {
using type = R ;
};
template struct product_helper;
template class R, typename... Ts>
struct product_helper < R > { // stop condition
using type = R< Ts...>;
};
template class R, typename... Ts>
struct product_helper < R >, Ts... > { // catches first empty tuple
using type = R<>;
};
template class R, typename... Ts, typename... Rests>
struct product_helper < R, R<>, Rests... > { // catches any empty tuple except first
using type = R<>;
};
template class R, typename... X, typename H, typename... Rests>
struct product_helper < R, R, Rests... > {
using type1 = R >::type...>;
using type = typename product_helper::type;
};
template class R, typename... X, template class Head, typename T, typename... Ts, typename... Rests>
struct product_helper < R, Head, Rests... > {
using type1 = R >::type...>;
using type2 = typename product_helper , R >::type;
using type3 = typename cat2::type;
using type = typename product_helper::type;
};
template class R, typename... Ts> struct product;
template class R>
struct product < R > { // no input, R specifies the return type
using type = R<>;
};
template class R, template class Head, typename... Ts, typename... Tail>
struct product , Tail... > { // R is the return type, Head is the first input list
using type = typename product_helper< R...>, Tail... >::type;
};
Here is a compilable example of how the code can be used.