If I want to write a function summing two std::array, I would do something like:
template<class T, std::size_t N>
auto sum(const std::array<T, N>& a, const std::array<T, N>& b)
{
std::array< decltype(a[0] + b[0]), N> result; //the underlying type is not necessarily T
for (std::size_t i = 0; i < N; ++i)
{
result[i] = a[i] + b[i];
}
return result;
}
How would I write this function in case decltype(a[0] + b[0]) is not default-constructible?
Here is an example on compiler explorer: https://godbolt.org/z/qndGfhehM
Ideally, I want to directly create and initialize the std::array, but I failed to write a function for any N.
I would like to rely only on a C++ standard.
I guess the implementation can be achieved with an intermediate std::vector, but it would require copies.
I tried to write a recursive template function such as:
template<class T, std::size_t N>
auto operator+(const std::array<T, N>& a, const std::array<T, N>& b)
{
if constexpr (N > 1)
{
return {a[0] + b[0], ???};
}
else
{
return {a[0] + b[0]};
}
}
but I don't know what to write instead of the ???.
I am aware that std::index_sequence exists, but I don't know how to use it in this case.
Using std::index_sequence is a two-step process:
Create it and pass it to a helper which uses the indices for your task.
A generic lambda with explicit template-arguments is enough for that (for earlier standards, use a normal function and more arguments):
template <class T, std::size_t N>
auto operator+(const std::array<T, N>& a, const std::array<T, N>& b)
{
return [&]<std::size_t... Is>(std::index_sequence<Is...>){
return std::array<decltype(a[0] + b[0]), N>{(a[Is] + b[Is])...};
}(std::make_index_sequence<N>());
}
Something along these lines:
template <typename T, std::size_t N, std::size_t... Is>
auto sum_helper(const std::array<T, N>& a, const std::array<T, N>& b,
std::index_sequence<Is...>) {
return std::array<decltype(a[0] + b[0]), N>{(a[Is] + b[Is])...};
}
template<class T, std::size_t N>
auto sum(const std::array<T, N>& a, const std::array<T, N>& b)
{
return sum_helper(a, b, std::make_index_sequence<N>{});
}
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With