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 type
  • Extent: number of elements in the sequence, or std::dynamic_extent for runtime-sized spans

# Semantic model

  • span refers 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.
  • span is 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 typeDefinition
element_typeT
value_typestd::remove_cv_t<T>
size_typestd::size_t
difference_typestd::ptrdiff_t
pointerT*
const_pointerconst T*
referenceT&
const_referenceconst T&
iteratorcontiguous iterator over the element sequence
const_iteratorstd::const_iterator<iterator>
reverse_iteratorstd::reverse_iterator<iterator>
const_reverse_iteratorstd::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

ConstantValue
extentExtent

# Reference map

AreaKey entries
Construction and lifetimespan::span, span::operator=
Iteratorsbegin, cbegin, end, cend, rbegin, crbegin, rend, crend
Element accessfront, back, at, operator[], data
Observerssize, size_bytes, empty, extent
Subviewsfirst, last, subspan
Non-member surfaceas_bytes, as_writable_bytes, dynamic_extent
Related supportdeduction guides

# Helper templates

  • ranges::enable_borrowed_range<std::span<T, Extent>> = true makes span a borrowed range.
  • ranges::enable_view<std::span<T, Extent>> = true makes span a 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

MacroValueStandardMeaning
__cpp_lib_span202002LC++20std::span
__cpp_lib_span202311LC++26std::span::at
__cpp_lib_span_initializer_list202311LC++26construction from std::initializer_list

# Defect reports

DRApplied toBehavior as publishedCorrect behavior
LWG 3203C++20it was unclear when pointers, iterators, and references to elements are invalidatedmade clear
LWG 3903C++20the declaration of span’s destructor was unnecessaryremoved the declaration
P2325R3C++20only spans of non-zero static extent were viewsany span is a view

# See also