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);
}
My question is how can i peel the first parameter of each of these packs and multiply them and then sum them with recursive call to reduced parameter pack of both the packs.
Esentially I want to implement : SUM(A[i] * B[i])
You can actually do that without recursion.
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);
}
There is no needs of recursion (if you don't want a C++11 constexpr
returning function).
Suggestion: instead of a couple of variadic arguments use a couple of C-style arrays as follows
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;
}
This way you have: (1) an homogeneous T
type instead a couple of variadic type lists and (2) that the two list must be of the same size N
or the function doesn't match. I suppose they are advantages if you want a sum(a[i] * b[i])
The function should be called with a couple of initialization list (that is: wrapping in brackets the two lists)
// print 70
std::cout << func({1, 2, 3, 4}, {5, 6, 7, 8}) << std::endl;
Different if you need a constexpr
function: the func()
can be constexpr
starting from C++14 but not in C++11.
If you want a C++11 constexpr
function you need it recursive but there no need of "peel the first parameter of each of these packs": you can use and index (with a default starting value of zero)
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};
}
-- EDIT --
The OP says
My whole aim is to do this using parameter packs only :)
I see...
Well, I suppose that, in C++11, you can use trick of the initialization of an unused array
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;
}
If you can use C++17, you can write
template <typename ... As, typename ... Bs>
auto func (As ... args1 ,int, int, Bs ...args2)
{
return ( (args1 * args2) + ... );
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.