#include <iostream>
#include <tuple>
namespace detail
{
template<std::size_t...IsN, std::size_t...Is, typename F>
void forEachNArgsImpl(std::index_sequence<IsN...>, std::index_sequence<Is...>, F) { }
template<std::size_t...IsN, std::size_t...Is, typename F, typename... Ts>
void forEachNArgsImpl(std::index_sequence<IsN...> isn, std::index_sequence<Is...>, F f, Ts... mXs)
{
f(std::get<IsN>(std::forward_as_tuple(std::forward<Ts>(mXs)...))...);
constexpr std::size_t N = sizeof...(IsN);
constexpr std::size_t is = sizeof...(Is);
forEachNArgsImpl(isn,
std::make_index_sequence<(is > N) ? sizeof...(Is) - N : 0>{},
f,
std::get<N + Is>(std::forward_as_tuple(std::forward<Ts>(mXs)...))...);
}
}
template<std::size_t N, typename F, typename... Ts> void forEachNArgs(F f, Ts... args)
{
static_assert(sizeof...(Ts) % N == 0, "Wrong number of arguments");
detail::forEachNArgsImpl(std::make_index_sequence<N>{}, std::make_index_sequence<sizeof...(Ts) - N>{}, f, std::forward<Ts>(args)...);
}
int main()
{
int result{0};
forEachNArgs<2>([&result](auto a1, auto a2)
{
result += (a1 * a2);
}, 2, 4, 3, 6);
std::cout << result << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHVwbGU+CgpuYW1lc3BhY2UgZGV0YWlsCnsKCiAgICB0ZW1wbGF0ZTxzdGQ6OnNpemVfdC4uLklzTiwgc3RkOjpzaXplX3QuLi5JcywgdHlwZW5hbWUgRj4KICAgIHZvaWQgZm9yRWFjaE5BcmdzSW1wbChzdGQ6OmluZGV4X3NlcXVlbmNlPElzTi4uLj4sIHN0ZDo6aW5kZXhfc2VxdWVuY2U8SXMuLi4+LCBGKSB7IH0KCiAgICB0ZW1wbGF0ZTxzdGQ6OnNpemVfdC4uLklzTiwgc3RkOjpzaXplX3QuLi5JcywgdHlwZW5hbWUgRiwgdHlwZW5hbWUuLi4gVHM+CiAgICB2b2lkIGZvckVhY2hOQXJnc0ltcGwoc3RkOjppbmRleF9zZXF1ZW5jZTxJc04uLi4+IGlzbiwgc3RkOjppbmRleF9zZXF1ZW5jZTxJcy4uLj4sIEYgZiwgVHMuLi4gbVhzKQogICAgewogICAgICAgIGYoc3RkOjpnZXQ8SXNOPihzdGQ6OmZvcndhcmRfYXNfdHVwbGUoc3RkOjpmb3J3YXJkPFRzPihtWHMpLi4uKSkuLi4pOwogICAgICAgIGNvbnN0ZXhwciBzdGQ6OnNpemVfdCBOID0gc2l6ZW9mLi4uKElzTik7CiAgICAgICAgY29uc3RleHByIHN0ZDo6c2l6ZV90IGlzID0gc2l6ZW9mLi4uKElzKTsKICAgICAgICBmb3JFYWNoTkFyZ3NJbXBsKGlzbiwKICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6bWFrZV9pbmRleF9zZXF1ZW5jZTwoaXMgPiBOKSA/IHNpemVvZi4uLihJcykgLSBOIDogMD57fSwKICAgICAgICAgICAgICAgICAgICAgICAgIGYsCiAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OmdldDxOICsgSXM+KHN0ZDo6Zm9yd2FyZF9hc190dXBsZShzdGQ6OmZvcndhcmQ8VHM+KG1YcykuLi4pKS4uLik7CiAgICB9Cgp9Cgp0ZW1wbGF0ZTxzdGQ6OnNpemVfdCBOLCB0eXBlbmFtZSBGLCB0eXBlbmFtZS4uLiBUcz4gdm9pZCBmb3JFYWNoTkFyZ3MoRiBmLCBUcy4uLiBhcmdzKQp7CglzdGF0aWNfYXNzZXJ0KHNpemVvZi4uLihUcykgJSBOID09IDAsICJXcm9uZyBudW1iZXIgb2YgYXJndW1lbnRzIik7CiAgICBkZXRhaWw6OmZvckVhY2hOQXJnc0ltcGwoc3RkOjptYWtlX2luZGV4X3NlcXVlbmNlPE4+e30sIHN0ZDo6bWFrZV9pbmRleF9zZXF1ZW5jZTxzaXplb2YuLi4oVHMpIC0gTj57fSwgZiwgc3RkOjpmb3J3YXJkPFRzPihhcmdzKS4uLik7Cn0KCgppbnQgbWFpbigpCnsKICAgIGludCByZXN1bHR7MH07CiAgICBmb3JFYWNoTkFyZ3M8Mj4oWyZyZXN1bHRdKGF1dG8gYTEsIGF1dG8gYTIpCiAgICB7CiAgICAgICAgcmVzdWx0ICs9IChhMSAqIGEyKTsKICAgIH0sIDIsIDQsIDMsIDYpOwoKICAgIHN0ZDo6Y291dCA8PCByZXN1bHQgPDwgc3RkOjplbmRsOwp9