I am working on some code which is a state machine, and different classes are responsible for different kind of task, all of which are acquiring data. Upon completing the data acquisition, the data needs to be sent away. The class responsible looks something like this:
class SendBuffer {
std::uint8_t* get_position(/*some arguments to determine buffer*/) {
return &buffer[/*at determined location*/];
}
private:
std::array<std::uint8_t, MAX_SIZE> buffer;
};
Of course, this is not safe at all, because the returned pointer has no information of how long the dedicated slice in the buffer is, etc.
I considered returning std::span<std::uint8_t>
instead of a raw pointer, but I was wondering what the best practices are here.
Using std::span
(cppreference) is the way to go. It can be initialized from views, as mentioned in the comments. Alternatively span
's member functions provide useful utilities. In case of the question, a single value can be returned as a span using the subspan(offset, extent)
function.
std::span get_position(std::size_t i) {
return std::span(buffer).subspan(i, 1);
}
For a single value returning a reference might be more useful though. But for subranges of the buffer, span
's subspan
, first
and last
are convenient. Some examples:
std::array<T, N> buffer;
std::span buffer_view{buffer}; // of type std::span<T, N>
buffer_view.subspan(a) // range from indices [a, end)
buffer_view.subspan(a, b) // range from indices [a, a+b)
buffer_view.subspan(a).first<B>() // range from indices [a, a+B) with compile time B
// thus returns std::span<T, B>
Note that subspan
, first
and last
have static and dynamic overloads
buffer_view.subspan<A, B>() // std::span<T, B>
buffer_view.subspan(a, b) // std::span<T, std::dynamic_extent>
buffer_view.first<C>() // std::span<T, C>
buffer_view.first(c) // std::span<T, std::dynamic_extent>
buffer_view.last<D>() // std::span<T, D>
buffer_view.last(d) // std::span<T, std::dynamic_extent>
Where upper case letters denote compile time constants and lower case letters can also be run time sizes.