簡體   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