How to create the Cartesian product of a type list?
c++, c++11, variadic-templates
Solution
Somehow my brain is fried: I think I'm using more code than is needed but, at least, it has the desired results (although I didn't fix the memory leak):
#include <iostream>
#include <typeinfo>
#include <cxxabi.h>
template<typename...> struct type_list {};
template<typename T1, typename T2> struct type_pair {};
template<typename T, typename... Rest>
struct row
{
typedef type_list<type_pair<T,Rest>...> type;
};
template <typename... T> struct concat;
template <typename... S, typename... T>
struct concat<type_list<S...>, type_list<T...>>
{
typedef type_list<S..., T...> type;
};
template <typename... T>
struct expand
{
typedef type_list<T...> type;
};
template <> struct expand<> { typedef type_list<> type; };
template <typename... T, typename... L>
struct expand<type_list<T...>, L...>
{
typedef typename concat<typename expand<T...>::type, typename expand<L...>::type>::type type;
};
template<typename... T>
struct cross_product
{
typedef typename expand<type_list<typename row<T,T...>::type...>>::type type;
};
int main()
{
int s;
typedef cross_product<int, float, short>::type result;
std::cout << abi::__cxa_demangle(typeid(result).name(), 0, 0, &s) << std::endl;
return 0;
}
Problem
I'd like to create the cross product of a list of types using variadic templates. Here's what I have so far: ``` #include <iostream> #include <typeinfo> #include <cxxabi.h> template<typename...> struct type_list {}; template<typename T1, typename T2> struct type_pair {}; template<typename T, typename... Rest> struct row { typedef type_list<type_pair<T,Rest>...> type; }; template<typename... T> struct cross_product { typedef type_list<typename row<T,T...>::type...> type; }; int main() { int s; typedef cross_product<int, float, short>::type result; std::cout << abi::__cxa_demangle(typeid(result).name(), 0, 0, &s) << std::endl; return 0; } ``` This program outputs: ``` $ g++ -std=c++0x cross_product.cpp ; ./a.out type_list<type_list<type_pair<int, int>, type_pair<int, float>, type_pair<int, short> >, type_list<type_pair<float, int>, type_pair<float, float>, type_pair<float, short> >, type_list<type_pair<short, int>, type_pair<short, float>, type_pair<short, short> > > ``` But I'd like it to output: ``` type_list<type_pair<int,int>, type_pair<int,float>, type_pair<int,short>, type_pair<float,int>,...> ``` That is, without the nested `type_list`s. Is there a direct way to do this without the `row` helper, or should the solution "unwrap" the nested `type_list`s somehow?