Search code examples
c++c++14metaprogrammingtemplate-meta-programming

Vector product of multiple vectors using meta function


Given a vector like:

  template<int... elements>
  struct vec;

How is it possible to create a metafunction which can do multiply element by element all provided vectors. For example

   template<typename ...AllVecs>
    struct multiVecs
   {
     using type = .... 
   }

where type would execute all products element by element. For example given three vecs:

   multiVecs< vec<0,1,2>, vec<1,2,3>, vec<2,3,4> >

i should get a vec<0*1*2, 1*2*3, 2*3*4>


Solution

  • Let's start with the two vector product, and go from there.

    template <typename lhs, typename rhs>
    struct multiplies;
    
    template <int... lhs, int... rhs>
    struct multiplies<vec<lhs...>, vec<rhs...>> {
        static_assert(sizeof...(lhs) == sizeof...(rhs), "Vector arity mismatch");
        using type = vec<(lhs * rhs)...>
    };
    
    template <typename lhs, typename rhs>
    using multiplies_t = typename multiplies<lhs, rhs>::type;
    

    This works fine, so now we just fold it over the pack.

    Unfortunately C++14 doesn't have fold expressions, so we have to do it longhand.

    template <typename...>
    struct multiVecs;
    
    template <typename... Ts>
    using multiVecs_t = typename multiVecs<Ts...>::type;
    
    template <typename result>
    struct multiVecs<result> {
        using type = result;
    };
    
    template <typename first, typename second, typename... rest>
    struct multiVecs<first, second, rest...> {
        using type = multiVecs_t<multiplies<first, second>, rest...>;
    };
    

    This is also fine