Я бы сгруппировал double
и container
, чтобы упростить код до:
template <typename C, typename ... Cs>
C sum(const C& c0, const Cs&... cs)
{
auto result = c0;
for (int i = 0; i < result.size(); ++i)
#if 0 // C++17
result[i] += (cs[i] + ...);
#else // C++11/C++14
const int dummy[] = {0, (static_cast<void>(result[i] += cs[i]), 0)...};
static_cast<void>(dummy); // avoid warning for unused variable.
#endif
return result;
}
Итак, для группировки что-то вроде:
template <typename C>
struct MulContainer
{
auto operator [](int i) const { return d * c[i]; }
double d;
const C& c;
};
Так что для вызова вместоиз
sum(c0, a1, c1, a2, c2);
у вас будет:
sum(c0, MulContainer{a1, c1}, MulContainer{a2, c2});
Если действительно необходимо, с std::index_sequence
у вас все еще может быть синтаксис первого вызова.
template <typename C, std::size_t... Is, typename Tuple>
C sum_impl(const C& c0, std::index_sequence<Is...>, const Tuple& t)
{
return sum(c0, MulContainer{std::get<2 * Is>(t), std::get<2 * Is + 1>(t)}...);
}
template <typename C, typename ... Ts>
C final_sum(const C& c0, const Ts&... ts)
{
static_assert(sizeof...(Ts) % 2 == 0);
return sum_impl(c0, std::make_index_sequence<sizeof...(Ts) / 2>{}, std::tie(ts...));
}
std::index_sequence
это C ++ 14, но может быть реализовано в C ++ 11.