Daily bit(e) of C++ | std::span

Šimon Tóth
1 min readFeb 23, 2023

--

Daily bit(e) of C++ #53, The C++20 contiguous range view std::span

When interacting with legacy code or C APIs, passing data around as C arrays might be unavoidable. This brings with it the potential for errors.

C++20 introduced std::span, a view that can wrap a contiguous memory block and provides a contiguous range interface.

We can use a std::span to bridge the C and C++ code and to access the underlying byte representation.

#include <cstdint>
#include <span>
#include <vector>
#include <ranges>

char buffer[16];
auto view = std::span(buffer);
// Call C API using a wrapped buffer
size_t cnt = read(view.data(), view.size());
// Process a sub-view based on the number of actually read bytes
for (auto v : view.subspan(0, cnt)) {}

char* buff;
size_t length;
int ret = get_data(&buff, &length);
if (ret != 0) { return ret; }
// Wrap a C buffer into a std::span
auto buffer_view = std::span(buff, length);

// std::span works as any other range, e.g. reverse iteration:
for (auto it = buffer_view.rbegin(); it != buffer_view.rend(); ++it) {}
// or combining with views:
for (auto v : buffer_view | std::views::drop(16)) {}

std::vector<Data> data{{2,3},{1,5},{4,4}};
// Acces the underlying representation:
std::span<std::byte> bytes = std::as_writable_bytes(std::span(data));

Open the example in Compiler Explorer.

--

--

Šimon Tóth

20 years worth of Software Engineering experience distilled into easily digestible articles.