Info
-
Did you know that C++11 allows calling functions with reference-to-array parameters from an initializer list?
Example
consteval auto foo(const auto (&value)[1]) { return value[0]; }
static_assert(42 == foo({42}));
Puzzle
Can you implement sum_n which sums given list of parameters?
// TODO sum_n
static_assert(1==sum_n({1}));
static_assert(1+2==sum_n({1}, {2}));
static_assert(1+2+3+4==sum_n({1, 2}, {3, 4}));
Solutions
consteval auto sum_n(const auto ...x)
{
return (x + ...);
}
consteval auto sum_n(const auto (&... x)[1])
{
return sum_n(x[0]...);
}
consteval auto sum_n(const auto (&... x)[2])
{
return sum_n(x[1]...) + sum_n(x[0]...);
}
template <typename... Ts, int... Ns>
consteval auto sum_n(const Ts (&...x)[Ns]) {
return (... + std::ranges::fold_left(x, Ts{}, std::plus{}));
}
template <auto... Ns>
constexpr auto sum_n(auto (&&...values)[Ns]) {
auto sum = 0;
return ([&] {
for (auto value : values) {
sum += value;
}
}(), ..., sum);
}
template<auto N>
consteval auto sum_n(const auto (&...array)[N]) {
auto result = (std::accumulate(array, array + N, 0) + ...);
return result;
}
template<class... Lists, int ...N>
consteval auto sum_n(const Lists (&...v)[N]) {
return (std::accumulate(v, v+N, 0) + ...);
}