I am trying to create a std::array<uint8_t,N> from a std::span<uint8_t,N> but I cannot find a way to do so without memcpy, std::copy, or std::ranges::copy which don’t protect me against wrong specification of destination array size.
#include <algorithm>
#include <array>
#include <iostream>
#include <span>
int main(int argc, char **argv) {
constexpr size_t N = 10;
std::array<uint8_t, N> original;
std::span span(original); // of type std::span<uint8,N>
std::array copy1(span); // does not work
std::array<uint8_t, N> copy2(span); // does not work
std::array<uint8_t, N> copy3(begin(span), end(span)); // does not work
// ugly stuff that works, but does not protect me if I specify wrong array size
constexpr size_t M{N - 1}; //oops, leads to array overflow
std::array<uint8_t, M> copy4;
std::copy(begin(span), end(span), copy4.begin());
std::ranges::copy(span, copy4.begin());
return 0;
}
What is the idiomatic way to do this in modern C++?
>Solution :
but I cannot find a way to do so without
memcpy,std::copy, or
std::ranges::copywhich don’t protect me against wrong specification
of destination array size.
If a span has a static extent, its size() can be implemented as a constant expression, which works on current mainstream compilers:
std::array<uint8_t, span.size()> copy4;
std::ranges::copy(span, copy4.begin());
Or you can get the size value through its static member constant extent (like std::array<uint8_t, span.extent>), which is guaranteed to work.