[英]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.