How to create the Cartesian product of a type list?

前端 未结 9 1446
夕颜
夕颜 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:53

    Really enjoyed this "homework" assignment :)

    Both solutions below create a class full of type_list typedefs, along with member functions that will check to see if a given list of types exist in the class as a type_list.

    The first solution creates all possible combinations of types from 1 to N types per type_list (the width parameter defines N). The second solution creates only pairs of types.

    First Solution

    template struct type_list { typedef type_list type; };
    
    template struct xprod_tlist_ {};
    
    template
    struct xprod_tlist_<1, type_list, Us...> {};
    
    template
    struct xprod_tlist_, Us...>
    : type_list...
    , xprod_tlist_, Us...>... {};
    
    template struct xprod_tlist
    : type_list..., xprod_tlist_, Ts...>... {
        template struct exists
        : std::is_base_of, xprod_tlist> {};
    
        template struct assert_exists {
            static_assert(exists::value, "Type not present in list");
        };
    };
    

    Usage:

    typedef xprod_tlist<5, int, char, string, float, double, long> X;
    
    //these pass
    X::assert_exists assert_test1;
    X::assert_exists assert_test2;
    
    //these fail
    X::assert_exists assert_test3;
    X::assert_exists assert_test4;
    
    //true
    auto test1 = X::exists::value;
    auto test2 = X::exists::value;
    
    //false
    auto test3 = X::exists::value;
    auto test4 = X::exists::value;
    

    Second Solution

    template struct type_pair { typedef type_pair type; };
    template struct type_list {};
    template struct xprod_tlist_ {};
    
    template
    struct xprod_tlist_, type_list>
    : type_pair..., xprod_tlist_, type_list> {};
    
    template
    struct xprod_tlist : xprod_tlist_, type_list> {
        template struct exists
        : std::is_base_of, xprod_tlist> {};
    
        template struct assert_exists {
            static_assert(exists::value, "Type not present in list");
        };
    };
    

    Usage:

    typedef xprod_tlist X;
    
    //these pass
    X::assert_exists assert_test1;
    X::assert_exists assert_test2;
    X::assert_exists assert_test3;
    X::assert_exists assert_test4;
    X::assert_exists assert_test5;
    X::assert_exists assert_test6;
    X::assert_exists assert_test7;
    X::assert_exists assert_test8;
    X::assert_exists assert_test9;
    
    //this fails
    X::assert_exists assert_test10;
    
    //true
    auto test1 = X::exists::value;
    auto test2 = X::exists::value;
    auto test3 = X::exists::value;
    auto test4 = X::exists::value;
    auto test5 = X::exists::value;
    auto test6 = X::exists::value;
    auto test7 = X::exists::value;
    auto test8 = X::exists::value;
    auto test9 = X::exists::value;
    
    //false
    auto test10 = X::exists::value;
    

提交回复
热议问题