c++c++20c++-faqcpp-core-guidelinesstd-span

What is a "span" and when should I use one?


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++17 standard library.

So what is this mysterious span<T>, and why (or when) is it a good idea to use it?


Solution

  • What is it?

    A span<T> is:

    It was formerly known as an array_view and even earlier as array_ref.

    When should I use it?

    First, when not to use spans:

    Now for when to actually use a span:

    Use span<T> (respectively, span<const T>) instead of a free-standing T* (respectively const T*) when the allocated length or size also matter. So, replace functions like:

    void read_into(int* buffer, size_t buffer_size);
    

    with:

    void read_into(span<int> buffer);
    

    Why should I use it? Why is it a good thing?

    Oh, spans are awesome! Using a span...

    There's even more motivation for using spans, which you could find in the C++ core guidelines - but you catch the drift.

    But is it in the standard library?

    edit: Yes, std::span was added to C++ with the C++20 version of the language!

    Why only in C++20? Well, While the idea is not new - its current form was conceived in conjunction with the C++ core guidelines project, which only started taking shape in 2015. So it took a while.

    So how do I use it if I'm writing C++17 or earlier?

    It's part of the Core Guidelines's Support Library (GSL). Implementations:

    The GSL implementation does generally assume a platform that implements C++14 support [12]. These alternative single-header implementations do not depend on GSL facilities:

    Note that these different span implementations have some differences in what methods/support functions they come with; and they may also differ somewhat from the version adopted into the standard library in C++20.


    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 Eerd).

    There is also a multi-dimensional extension of spans: mdspans; see this SO question.