Search code examples
c++c++20template-meta-programming

Cartesian product of list of templates and list of types to instantiate them with


Not sure if title is descriptive, but what I would like is this:

input:

  1. list of templates(in my case containers) taking 1 (required, can be more optional) type arguments
  2. list of types

output:

"cartesian product" where each template in first set is instantiated with every type in second set.

example:

template_list<std::vector, std::set> x type_list<int, double> => 
type_list<std::vector<int>, std::vector<double>, std::set<int>, std::set<double>>

I found this question, but that is about a case when elements of both sets are types.

How to create the Cartesian product of a type list?

I presume that what I want is impossible without macros, but it may be possible that I am missing something.


Solution

  • As in my answer on he linked question, with Boost.Mp11, this is a short one-liner (as always):

    using templates = mp_list<mp_quote<std::vector>, mp_quote<std::set>>;
    using types = mp_list<int, double>;
    
    using result = mp_product<
        mp_invoke_q,
        templates, types>;
    
    static_assert(std::same_as<
        result,
        mp_list<std::vector<int>,
                std::vector<double>,
                std::set<int>,
                std::set<double>
                >>);
    

    Demo.

    Note that you need templates as mp_list<mp_quote<C1>, mp_quote<C2>> instead of template_list<C1, C2>, since metaprogramming is lot easier if everything is a type. But that's not a huge burden.