Given this type
template<std::size_t N, int ...content>
struct list {
inline int reduce() {
int result = 0;
constexpr int arr[N] = { content... };
for(std::size_t k = 0; k < N; ++k) {
result += arr[k];
}
return result;
}
};
I'd like to implement a function add
, which returns a new list containing the element-by-element addition of the two input lists.
In other words (pseudo-code):
add([a0, a1, a2], [b0, b1]) -> [a0 + b0, a1 + b2, a2]
Problem:
Here is how I would do it:
#include <iostream>
#include <utility>
template<std::size_t N, int ...content>
struct list {
inline int reduce() {
int result = 0;
constexpr int arr[N] = { content... };
for(std::size_t k = 0; k < N; ++k) {
result += arr[k];
}
return result;
}
};
template <std::size_t I, int ...A>
constexpr int list_at(list<sizeof...(A),A...>)
{
if constexpr (I < sizeof...(A))
{
constexpr int arr[] {A...};
return arr[I];
}
else
{
return 0;
}
}
template <int ...A, int ...B, std::size_t ...I>
constexpr auto list_sum_low(list<sizeof...(A),A...>,
list<sizeof...(B),B...>,
std::index_sequence<I...>)
{
return list<sizeof...(I), (list_at<I>(list<sizeof...(A),A...>{}) +
list_at<I>(list<sizeof...(B),B...>{}))...>{};
}
template <int ...A, int ...B>
constexpr auto list_sum(list<sizeof...(A),A...>, list<sizeof...(B),B...>)
{
constexpr int a = sizeof...(A), b = sizeof...(B);
return list_sum_low(list<a,A...>{}, list<b,B...>{},
std::make_index_sequence<(a > b ? a : b)>{});
}
template <int ...A>
void print_list(list<sizeof...(A),A...>)
{
(void(std::cout << ' ' << A) , ...);
}
int main()
{
constexpr auto x = list_sum(list<4, 1,2,3,4>{}, list<2, 10,20>{});
print_list(x);
}
Also, note that there is no need have size_t N
template parameter for class list
. Parameter packs know their own size.