【问题标题】:Vector product of multiple vectors using meta function使用元函数的多个向量的向量积
【发布时间】:2021-10-11 06:11:58
【问题描述】:

给定一个向量:

  template<int... elements>
  struct vec;

如何创建一个可以将所有提供的向量逐个元素相乘的元函数。例如

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

其中 type 将逐个元素地执行所有产品。例如给定三个 vecs:

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

我应该得到一个vec&lt;0*1*2, 1*2*3, 2*3*4&gt;

【问题讨论】:

  • 如果vecs 之一有不同数量的参数怎么办?例如:multiVecs&lt;vec&lt;0,1,2&gt;, vec&lt;1,2,3, 4&gt;&gt;?

标签: c++ c++14 metaprogramming template-meta-programming


【解决方案1】:

让我们从两个向量积开始,然后从那里开始。

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,所以现在我们把它折叠起来。

不幸的是,C++14 没有折叠表达式,所以我们必须用手写的。

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

【讨论】:

  • 哇,很好地打包了参数......
【解决方案2】:

C++17 解决方案:

template<int... Elements>
struct vec;

template<int Element, class... Vec>
struct vec_impl { };

template<class Vec>
struct to_vec_impl;

template<int First, int... Rest>
struct to_vec_impl<vec<First, Rest...>> {
  using type = vec_impl<First, vec<Rest...>>;
};

template<>
struct to_vec_impl<vec<>> {
  using type = vec_impl<-1>;
};

template<class Result_vec, class... Vecs>
struct gen_vec_impl;

template<int... Products, template<int, class...> class... VecImpls, 
         int... First, class... Vecs>
struct gen_vec_impl<vec<Products...>, VecImpls<First, Vecs>...>
     : gen_vec_impl<vec<Products..., (First * ... * 1)>, 
                    typename to_vec_impl<Vecs>::type...> 
{ };

template<int... Products, template<int, class...> class... VecImpls>
struct gen_vec_impl<vec<Products...>, VecImpls<-1>...> {
  using type = vec<Products...>;
};

template<class... AllVecs>
struct multiVecs {
  using type = typename gen_vec_impl<
    vec<>, typename to_vec_impl<AllVecs>::type...>::type;
};

Demo.

【讨论】:

  • 有点解释会很好,就像其他答案一样!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 1970-01-01
  • 2018-10-10
  • 1970-01-01
  • 2018-05-09
  • 1970-01-01
  • 2015-07-07
相关资源
最近更新 更多