Section
std::span
std::span is a lightweight non-owning view over a contiguous sequence of objects.
A span can have either a static extent encoded in its type or a dynamic extent carried at runtime. In both cases it provides a container-like interface without owning storage.
# Declarations
template< class T, std::size_t Extent = std::dynamic_extent >
class span;
(since C++20)
# Template parameters
T: element typeExtent: number of elements in the sequence, or std::dynamic_extent for runtime-sized spans
# Semantic model
spanrefers to existing contiguous storage; it does not allocate or own elements.- A static-extent span carries the extent in its type, while a dynamic-extent span stores the size at runtime.
- Copying a span copies only the view state, not the underlying sequence.
spanis the standard-library vocabulary type for “borrowed contiguous range”.
# Example
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <span>
template<class T, std::size_t N>
[[nodiscard]]
constexpr auto slide(std::span<T, N> s, std::size_t offset, std::size_t width)
{
return s.subspan(offset, offset + width <= s.size() ? width : 0U);
}
void println(const auto& seq)
{
for (const auto& elem : seq)
std::cout << elem << ' ';
std::cout << '\n';
}
int main()
{
constexpr int a[]{0, 1, 2, 3, 4, 5, 6, 7, 8};
constexpr static std::size_t width{6};
for (std::size_t offset{}; ; ++offset)
if (auto s = slide(std::span{a}, offset, width); !s.empty())
println(s);
else
break;
}
This is the core span pattern: hand a borrowed window of contiguous storage to an algorithm without copying or owning the data.
# Member types
| Member type | Definition |
|---|---|
element_type | T |
value_type | std::remove_cv_t<T> |
size_type | std::size_t |
difference_type | std::ptrdiff_t |
pointer | T* |
const_pointer | const T* |
reference | T& |
const_reference | const T& |
iterator | contiguous iterator over the element sequence |
const_iterator | std::const_iterator<iterator> |
reverse_iterator | std::reverse_iterator<iterator> |
const_reverse_iterator | std::const_iterator<reverse_iterator> |
iterator is mutable when T is not const. This is one of the key differences between span<T> and read-only view types such as std::basic_string_view.
# Member constant
| Constant | Value |
|---|---|
extent | Extent |
# Reference map
| Area | Key entries |
|---|---|
| Construction and lifetime | span::span, span::operator= |
| Iterators | begin, cbegin, end, cend, rbegin, crbegin, rend, crend |
| Element access | front, back, at, operator[], data |
| Observers | size, size_bytes, empty, extent |
| Subviews | first, last, subspan |
| Non-member surface | as_bytes, as_writable_bytes, dynamic_extent |
| Related support | deduction guides |
# Helper templates
ranges::enable_borrowed_range<std::span<T, Extent>> = truemakesspana borrowed range.ranges::enable_view<std::span<T, Extent>> = truemakesspana view.
# Deduction guides
The class has deduction guides so construction from arrays and other contiguous sources can infer T and, when appropriate, the extent.
# Notes
Specializations of std::span were already trivially copyable in practice before that guarantee became a formal requirement in C++23.
# Feature-test macros
| Macro | Value | Standard | Meaning |
|---|---|---|---|
__cpp_lib_span | 202002L | C++20 | std::span |
__cpp_lib_span | 202311L | C++26 | std::span::at |
__cpp_lib_span_initializer_list | 202311L | C++26 | construction from std::initializer_list |
# Defect reports
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 3203 | C++20 | it was unclear when pointers, iterators, and references to elements are invalidated | made clear |
| LWG 3903 | C++20 | the declaration of span’s destructor was unnecessary | removed the declaration |
| P2325R3 | C++20 | only spans of non-zero static extent were views | any span is a view |