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