Recently I've gotten suggestions to use span<T>
's in my code, or have seen some answers here on the site which use span
's - supposedly some kind of container. But - I can't find anything like that in the C++ standard library.
So what is this mysterious span<T>
, and why (or when) is it a good idea to use it if it's non-standard?
What is it?
A
span<T>
is:struct { T * const ptr; size_t length; }
with a bunch of convenience methods.It was formerly known as an
array_view
and even earlier asarray_ref
.When should I use it?
First, when not to use it:
std::sort
,std::find_if
,std::copy
and all of those super-generic templated functions.Now for when to actually use it:
Why should I use it? Why is it a good thing?
Oh, spans are awesome! Using a
span
...means that you can work with that pointer+length / start+end pointer combination like you would with a fancy, pimped-out standard library container, e.g.:
for (auto& x : my_span) { /* do stuff */ }
std::find_if(my_span.begin(), my_span.end(), some_predicate);
... but with absolutely none of the overhead most container classes incur.
lets the compiler do more work for you sometimes. For example, this:
becomes this:
... which will do what you would want it to do. See also Guideline P.5.
is the reasonable alternative to pass
const vector<T>&
to functions when you expect your data to be contiguous in memory. No more getting scolded by high-and-mighty C++ gurus.facilitates static analysis, so the compiler might be able to help you catch silly bugs.
span
's methods will have some bounds-checking code within#ifndef NDEBUG
...#endif
)There's even more motivation for using
span
s, which you could find in the C++ core guidelines - but you catch the drift.Why is it not in the standard library (as of C++17)?
It is in the standard library - but only as of C++20. The reason is that it's still pretty new in its current form, conceived in conjunction with the C++ core guidelines project, which has only been taking shape since 2015. (Although as commenters point out, it has earlier history.)
So how do I use it if it's not in the standard library yet?
It's part of the Core Guidelines's Support Library (GSL). Implementations:
gsl/span
span<T>
.Note that you can use it with earlier versions of the language standard - C++11 and C++14, not just C++17.
Further reading: You can find all the details and design considerations in the final official proposal before C++17, P0122R7: span: bounds-safe views for sequences of objects by Neal Macintosh and Stephan J. Lavavej. It's a bit long though. Also, in C++20, the span comparison semantics changed (following this short paper by Tony van Eeerd).