繁体   English   中英

能够通过变量模板以点积形式在C ++ 11中将两个参数包相乘

[英]Ability to multiply two parameter packs in C++ 11 in dot product fashion via variadic templates

template<class...A, class...B> void func(A...arg1,int sz1, int sz2, B...arg2)
{
std::cout << "sizeof parameter pack for A = " << sizeof...(arg1) << std::endl;
std::cout << "sizeof parameter pack for B = " << sizeof...(arg2) << std::endl;
}

using namespace std;

int main(void)
{
   func<int,int,int,int>(1,2,3,4,4,4,5,6,7,8);

}

我的问题是我如何剥离这些包装中每个包装的第一个参数,然后将它们相乘,然后通过递归调用求和,以求得这两个包装中的简化参数包装。

基本上我想实现: SUM(A[i] * B[i])

您实际上可以做到这一点而无需递归。

template<class...A, class...B> int func(A...arg1, int sz1, int sz2, B...arg2)
{
    std::vector<int> p = {(arg1 * arg2)...};
    return std::accumulate(p.begin(), p.end(), 0);
}

不需要递归(如果您不希望C ++ 11 constexpr返回函数)。

建议:代替几个可变参数,使用几个C样式数组,如下所示

template <typename T, std::size_t N>
T func (T const (&a1)[N], T const (&a2)[N])
 {
   T ret {};

   for ( auto ui { 0u } ; ui < N ; ++ui )
      ret += a1[ui] * a2[ui];

   return ret;
 }

通过这种方式,您可以:(1)同构T类型,而不是几个可变参数类型列表,以及(2)两个列表必须具有相同的大小N或函数不匹配。 我想如果您想sum(a[i] * b[i])它们就是优势。

该函数应通过几个初始化列表来调用(即:将两个列表放在方括号中)

// print 70 
std::cout << func({1, 2, 3, 4}, {5, 6, 7, 8}) << std::endl;

如果需要constexpr函数,则有所不同: func()可以是从C ++ 14开始的constexpr ,但不能在C ++ 11中。

如果要使用C ++ 11 constexpr函数,则需要递归,但不需要“去掉这些包中的每个包的第一个参数”:可以使用和索引(默认起始值​​为零)。

template <typename T, std::size_t N>
constexpr T func (T const (&a1)[N], T const (&a2)[N], std::size_t pos = 0u)
 {
   return pos < N 
      ? a1[pos] * a2[pos] + func(a1, a2, pos+1u)
      : T{0};
 }

-编辑-

OP说

我的整个目标是仅使用参数包进行此操作:)

我懂了...

好吧,我想在C ++ 11中,您可以使用未使用的数组的初始化技巧

template <typename ... As, typename ... Bs>
auto func (As ... args1 ,int, int, Bs ...args2)
    -> typename std::common_type<As..., Bs...>::type
 {
   using unused = int[];

   typename std::common_type<As..., Bs...>::type ret{};

   (void)unused { 0, ( ret += args1 * args2, 0 ) ... };

   return ret;
 }

如果可以使用C ++ 17,则可以编写

template <typename ... As, typename ... Bs>
auto func (As ... args1 ,int, int, Bs ...args2)
 {
   return ( (args1 * args2) + ... );
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM