How to create the Cartesian product of a type list?

前端 未结 9 1447
夕颜
夕颜 2020-11-28 09:15

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 <         


        
9条回答
  •  庸人自扰
    2020-11-28 09:57

    C++17

    Working Demo

    Logic to concatenate type_lists to avoid nested type_list like you are asking for:

    // base case: 2 type_lists
    template
    auto concat(type_list, type_list) -> type_list;
    
    // recursive case: more than 2 type_lists
    template
    auto concat(type_list, type_list, Rest...) -> decltype(concat(type_list{}, Rest{}...));
    

    Note that these functions don't have (or need) implementations; this is a trick to avoid class template specialization (I learned it from Hana Dusikova's compile time regular expressions)

    Then, simplifying your row and cross_product impls as pairs and cross_product_impl, respectively:

    template
    using pairs = type_list...>;
    
    template
    auto cross_product_impl()
    {
        if constexpr(sizeof...(T) == 0)
            return type_list<> {};
        if constexpr(sizeof...(T) == 1)
            return type_list...>{};
        if constexpr(sizeof...(T) > 1)
            return concat(pairs{}...);
    }
    

    if constexpr allows us to more easily express the logic, I think.

    Finally a type alias for cross_product that gives us what the type would be if we theoretically invoked cross_product_impl:

    template
    using cross_product = decltype(cross_product_impl());
    

    Usage basically the same as before:

    cross_product result;
    

提交回复
热议问题