Search code examples
c++c++17protocol-buffers

How to fill std::array from protobuf repeatedField?


From a RepeatedField which is defined to have exactly N elements, I am filling up an std::array.

std::array<int, 6> entry;
size_t i = 0;
for (const auto& item: msg.items()){
  assert(i < 6);
  entry[i++] = item;
}

This works fine, but is there a better way to initialize it? filling up std::vector works fine with initialization lists, but std::array is really different.

Is it possible to use RepeatedFields in aggregate initialization of structs contaning std::array ?

What I tried so far does not even compile:

entry = {msg.items().begin(), msg.items().end()};

Which is understandable, because std::array doesn't have a constructor accepting an std::initializer_list; But is what I am trying to do even possible?


Solution

  • the most simple way is use aggregate initialization directly

    assert(items.size() >= 6)
    std::array entry = {
       items[0],items[1],items[2],
       items[3],items[4],items[5],
    };
    

    or you can write a function to help you

    template<std::size_t N, typename C>
    auto get_array(C&& c){
        assert(c.size() >= N); // or ==, depend on the need
        return [&]<std::size_t ...Index>(std::index_sequence<Index...>){
            return std::array{c[Index]...};
        }(std::make_index_sequence<N>{});
    }
    
    void foo()
    {
        std::array entry = get_array<6>(items);
    }