Suppose I have
int foo(void* p, size_t size_in_bytes);
What I chose to do, and what I think is, shall we say, sound design-wise, is implement a class named
memory_region, which has all of the type-inspecific functionality of
gsl::span (hence, for example, it doesn't have a begin() or an end()). It is not the same thing as a span of bytes, IMO - and I can structurally never get them mixed up.
Here's my implementation (it's part of a repository of DBMS-related GPU kernels and a testing framework I'm working on, hence the CUDA-related snippet; and it depends on some GSL, in my case gsl-lite by MS'es should be ok too I think).