c++arraysc++17

Reference over array into array of reference


I have an array std::array<T, N> arr for some T, N and I'd like to get an array of reference over arr's elements like so std::array<std::reference_wrapper<T>, N> arr_ref.

But as a reference needs to be set at its initialization, I did not work out a solution. Therefore I would like to do something like that:

std::array<std::reference_wrapper<T>, N> ref{}
for (std::size_t i{0}; i < N; ++i)
  ref[i] = arr[i];

But at compile-time and at the initialization of ref.

I thought of using some variadic template magic to convert my initial array to a parameter pack and then take a reference to each element but I am not sure this is possible.

My last option would be an array of raw ptrs or of std::optional<std::reference_wrapper<T>>.


Solution

  • #include <array>
    #include <functional>
    #include <utility>
    #include <cstddef>
    
    template<typename x_Item, ::std::size_t x_count, ::std::size_t... x_index_pack>
    [[nodiscard]] auto wrap_impl
    (
        ::std::array<x_Item, x_count> & items
    ,   ::std::index_sequence<x_index_pack...>
    )
    {
        return ::std::array<::std::reference_wrapper<x_Item>, x_count>{items[x_index_pack]...};
    }
    
    template<typename x_Item, ::std::size_t x_count>
    [[nodiscard]] auto wrap
    (
        ::std::array<x_Item, x_count> & items
    )
    {
        return wrap_impl(items, ::std::make_index_sequence<x_count>{});
    }
    
    #include <iostream>
    
    int main()
    {
        ::std::array items{1, 2, 3};
        auto wrapped_items{wrap(items)};
        for (auto & wrapped_item: wrapped_items)
        {
            ::std::cout << wrapped_item.get() << ::std::endl;
        }
        return 0;
    }
    

    online compiler