span
class (C++ Standard Library)
Provides a lightweight view over a contiguous sequence of objects. A span
provides a safe way to iterate over and index into objects that are arranged back-to-back in memory. Such as objects stored in a built-in array, std::array
, or std::vector
.
If you typically access a sequence of back-to-back objects using a pointer and an index, a span
is a safer, lightweight alternative.
The size of a span
can be set at compile time by specifying it as a template argument, or at runtime by specifying dynamic_extent
.
Syntax
template<class T, size_t Extent = dynamic_extent>
class span;
Template parameters
T
The type of the elements in the span
.
Extent
The number of elements in the span
if specified at compile time. Otherwise std::dynamic_extent
if the number of elements will be specified at run-time.
Members
Type Definitions | Description |
---|---|
const_pointer |
The type of a pointer to a const element. |
const_reference |
The type of a reference to a const element. |
difference_type |
The type of a signed distance between two elements. |
element_type |
The type of a span element. |
iterator |
The type of an iterator for a span . |
pointer |
The type of a pointer to an element. |
reference |
The type of a reference to an element. |
reverse_iterator |
The type of a reverse iterator for a span . |
size_type |
The type for the result of the unsigned distance between two elements in the span . |
value_type |
The type of an element, without const or volatile qualifications. |
Constructor | Description |
span |
Construct a span . |
Iterator support | Description |
begin |
Get an iterator pointing to the first element in the span . |
end |
Get an iterator pointing to the end of the span . |
rbegin |
Get a reverse iterator pointing to the last element of the span ; that is, the beginning of the reversed span . |
rend |
Get a reverse iterator pointing to the front of the span ; that is, the end of the reversed span . |
Access elements | Description |
back |
Get the last element in the span . |
data |
Get the address of the first element in the span . |
front |
Get the first element in the span . |
operator[] |
Access an element at a specified position. |
Observers | Description |
empty |
Test whether the span is empty. |
size |
Get the number of elements in the span . |
size_bytes |
Get the size of the span in bytes. |
Subviews | Description |
first |
Get a subspan from the front of the span . |
last |
Get a subspan from the back of the span . |
subspan |
Get a subspan from anywhere in the span . |
Operators | Description |
span::operator= |
Replace the span . |
span::operator[] |
Get the element at the specified position. |
Remarks
All span
member functions have constant time complexity.
Unlike array
or vector
, a span
doesn't "own" the elements inside it. A span
doesn't free any storage for the items inside it because it doesn't own the storage for those objects.
Requirements
Header: <span>
(since C++20)
Namespace: std
Compiler Option: /std:c++20
or later is required.
span::back
Get the last element in the span
.
constexpr reference back() const noexcept;
Return value
A reference to the last element in the span
.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
cout << mySpan.back();
}
2
span::begin
Get an iterator pointing at the first element in the span
.
constexpr iterator begin() const noexcept;
Return value
An iterator pointing at the first element in the span
.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
auto i = mySpan.begin();
cout << *i;
}
0
span::data
Get a pointer to the beginning of the span
data.
constexpr pointer data() const noexcept;
Return value
A pointer to the first item stored in the span
.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
auto i = mySpan.data();
cout << *i;
}
0
span::difference_type
The number of elements between two elements in a span
.
using difference_type = std::ptrdiff_t;
Example
#include <span>
#include <iostream>
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
span<int>::difference_type distance = mySpan.end() - mySpan.begin();
cout << distance << std::endl;
}
3
span::element_type
The type of the elements in the span
.
using element_type = T;
Remarks
The type is taken from the template parameter T
when a span
is created.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
span<int>::element_type et = mySpan[2];
cout << et << endl;
}
2
span::empty
Whether the span
contains elements.
constexpr bool empty() const noexcept;
Return value
Returns true
if this->size() == 0
. Otherwise false
.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
bool isEmpty = mySpan.empty(); // isEmpty == false
}
span::end
Get an iterator to the end of the span
.
constexpr iterator end() const noexcept;
Return value
An iterator pointing just beyond the end of the span
.
Remarks
end
is used to test whether an iterator has passed the end of its range.
Don't dereference the value returned by this iterator. Use it to identify whether the iterator has reached beyond the last element in the span
.
Example
// Iteration
for (auto it = s1.begin(); it != s1.end(); ++it)
{
cout << *it;
}
span::first
Get a subspan, taken from the front of this span
.
constexpr auto first(size_type count) const noexcept;
template <size_t count> constexpr auto first() const noexcept;
Parameters
count
The number of elements from the front of this span
to put in the subspan.
The number of elements is specified as a parameter to the template, or to the function, as illustrated below.
Return value
A span
that contains count
elements from the front of this span
.
Remarks
Use the template version of this function when possible to validate the count
at compile time, and to preserve info about the span
since it returns a span
of fixed extent.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
auto first2 = mySpan.first(2);
cout << "mySpan.first(2): ";
for (auto& i : first2)
{
cout << i;
}
cout << "\nmySpan.first<2>: ";
auto viewSpan = mySpan.first<2>();
for (auto& i : viewSpan)
{
cout << i;
}
}
mySpan.first(2): 01
mySpan.first<2>: 01
span::front
Get the first element in the span
.
constexpr reference front() const noexcept;
Return value
A reference to the first element in the span
.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
auto i = mySpan.front();
cout << i;
}
0
span::iterator
The type of an iterator
over span
elements.
using iterator = implementation-defined-iterator-type;
Remarks
This type serves as an iterator
over the elements in a span
.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
span<int>::iterator it = mySpan.begin();
cout << *it++ << *it++ << *it;
}
012
span::last
Get a subspan, taken from the end of this span
.
constexpr span<element_type, dynamic_extent> last(const size_type count) const noexcept;
template <size_t count> constexpr span<element_type, count> last() const noexcept;
Parameters
count
The number of elements from the end this span
to put in the subspan.
The number can be specified as a parameter to the template, or to the function, as illustrated below.
Return value
A span
containing the last count
elements from this span
.
Remarks
Use the template version of this function when possible to validate the count
at compile time, and to preserve info about the span
since it returns a span
of fixed extent.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
auto first2 = mySpan.last(2);
cout << "mySpan.last(2): ";
for (auto& i : last2)
{
cout << i;
}
cout << "\nmySpan.last<2>: ";
auto viewSpan = mySpan.last<2>();
for (auto& i : viewSpan)
{
cout << i;
}
}
mySpan.last(2): 12
mySpan.last<2>: 12
span::operator[]
Get the element in the span
at a specified position.
constexpr reference operator[](size_type offset) const;
Parameters
offset
Zero-based element in the span
to access.
Return value
A reference to the element at position offset
. If the position is invalid, the behavior is undefined.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
cout << mySpan[1];
}
1
span::operator=
Assign another span
to this one.
constexpr span& operator=(const span& other) noexcept = default;
Parameters
other
The span
to assign to this one.
Return value
*this
Remarks
Assignment does a shallow copy of the data pointer and the size. A shallow copy is safe because a span
doesn't allocate memory for the elements it contains.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
span<int> mySpan2;
mySpan2 = mySpan;
for (auto &i : mySpan2)
{
cout << it;
}
}
012
span::pointer
The types for a pointer, and const
pointer, to a span
element.
using pointer = T*;
using const_pointer = const T*;
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
// pointer
span<int>::pointer ptr = &mySpan[2];
*ptr = 9;
cout << mySpan[2];
// const pointer
span<int>::const_pointer cPtr = &mySpan[0];
// *cPtr = 9; error - const
cout << *cPtr;
}
90
span::rbegin
Get a reverse iterator pointing to the last element of this span
.
constexpr reverse_iterator rbegin() const noexcept;
Return value
An iterator pointing to the beginning of the reversed span
.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
for (auto rIt = s1.rbegin(); rIt != s1.rend(); ++rIt)
{
cout << *rIt;
}
}
210
span::reference
The types for a reference, and a const
reference, to a span
element.
using reference = T&;
using const_reference = const T&;
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
// reference
span<int>::reference ref = mySpan[0];
ref = 9;
cout << mySpan[0];
// const reference
span<int>::const_reference cRef = mySpan[1];
// cRef = 9; error because const
cout << cRef;
}
91
span::rend
Get a random-access iterator that points just beyond the end of the reversed span
.
constexpr reverse_iterator rend() const noexcept;
Return value
A reverse iterator to the placeholder following the last element in the reversed span
; that is, the placeholder before the first element in the unreversed span
.
Remarks
rend
is used with a reversed span
just as span::end
is used with a span
. Use it to test to whether a reverse iterator has reached the end of its span
.
The value returned by rend
shouldn't be dereferenced.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
for (auto rIt = s1.rbegin(); rIt != s1.rend(); ++rIt)
{
cout << *rIt;
}
}
span::reverse_iterator
The type of a reverse iterator for a span
.
using reverse_iterator = std::reverse_iterator<iterator>;
Example
#include <span>
#include <iostream>
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
span<int>::reverse_iterator rIt = mySpan.rbegin();
cout << *rIt++ << *rIt++ << *rIt;
}
210
span::size
Get the number of elements in the span
.
constexpr size_t size() const noexcept;
Return value
The number of elements in the span
.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
cout << mySpan.size();
}
3
span::size_bytes
Get the size of the elements in the span
in bytes.
constexpr size_type size_bytes() const noexcept;
Return value
The number of bytes that all of the elements in the span
occupy; that is, sizeof(element_type)
multiplied by the number of elements in the span
.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
cout << mySpan.size_bytes(); // 3 elements * 4 (size of an int)
}
12
span::size_type
An unsigned type, suitable for storing the number of elements in a span
.
using size_type = size_t;
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
span<int>::size_type szType = mySpan.size();
cout << szType;
}
3
span::span
span
constructors.
constexpr span() noexcept
requires (Extent == 0 || Extent == dynamic_extent) = default;
template <class It>
constexpr explicit(Extent != dynamic_extent)
span(It first, size_type count) noexcept
template <class It, class End>
constexpr explicit(Extent != dynamic_extent)
span(It first, End last) noexcept(noexcept(last - first))
template <class T, size_t N>
requires (Extent == dynamic_extent || Extent == N) && is_convertible_v<T (*)[], T (*)[]>
constexpr span(array<T, N>& arr) noexcept
template <class T, size_t N>
requires (Extent == dynamic_extent || Extent == N) && is_convertible_v<const T (*)[], T (*)[]>
constexpr span(const array<T, N>& arr) noexcept
template <size_t N>
requires (Extent == dynamic_extent || Extent == N)
constexpr span(type_identity_t<T> (&arr)[N]) noexcept
template <class R>
constexpr explicit(Extent != dynamic_extent)
span(R&& r)
// default copy ctor
constexpr span(const span& other) noexcept = default;
// converting ctor
template <class T, size_t OtherExtent>
requires (Extent == dynamic_extent || OtherExtent == dynamic_extent ||
Extent == OtherExtent) && is_convertible_v<T (*)[], T (*)[]>
constexpr explicit(Extent != dynamic_extent && OtherExtent == dynamic_extent)
span(const span<T, OtherExtent>& other) noexcept
Parameters
arr
Construct a span
from an array.
count
Number of elements that will be in the span
.
first
Iterator to the first element in the span
.
last
Iterator to just past the last element in the span
.
N
The number of elements that will be in the span
.
other
Make a copy of this span
.
r
Construct a span
from the range R
.
Remarks
A span
doesn't free storage for items in the span
because it doesn't own the storage of the objects within it.
Constructor | Description |
---|---|
span() |
Construct an empty span . Only considered during overload resolution when the template parameter Extent is 0 or dynamic_extent . |
span(It first, size_type count) |
Construct a span from the first count elements from iterator first . Only considered during overload resolution when template parameter Extent isn't dynamic_extent . |
span(It first, End last) |
Construct a span from the elements in iterator first until the end last is reached. Only considered during overload resolution when template parameter Extent isn't dynamic_extent . It must be a contiguous_iterator . |
span(array<T, N>& arr) noexcept; span(const array<T, N>& arr) noexcept; span(type_identity_t<element_type> (&arr)[N]) noexcept; |
Construct a span from N elements of the specified array. Only considered during overload resolution when template parameter Extent is dynamic_extent or equals N . |
span(R&& r) |
Construct a span from a range. Only participates in overload resolution if template parameter Extent isn't dynamic_extent . |
span(const span& other) |
The compiler-generated copy constructor. A shallow copy of the data pointer is safe because the span doesn't allocate the memory to hold the elements. |
span(const span<OtherElementType, OtherExtent>& s) noexcept; |
Converting constructor: construct a span from another span . Only participates in overload resolution if template parameter Extent is dynamic_extent , or N is dynamic_extent or equals Extent . |
Example
#include <span>
using namespace std;
int main()
{
const int MAX=10;
int x[MAX];
for (int i = 0; i < MAX; i++)
{
x[i] = i;
}
span<int, MAX> span1{ x }; // fixed-size span: compiler error if size of x doesn't match template argument MAX
span<int> span2{ x }; // size is inferred from x
span<const int> span3 = span2; // converting constructor
span<int> span4( span2 ); // copy constructor
}
span::subspan
Get a subspan of this span
.
constexpr auto subspan(size_type offset, size_type count = dynamic_extent) const noexcept;
template <size_t offset, size_t count = dynamic_extent>
constexpr auto subspan() const noexcept
Parameters
count
The number of elements to put in the subspan. If count
is dynamic_extent
(the default value), then the subspan is taken from offset
to the end of this span
.
offset
The location in this span
to start the subspan.
Return value
A span
starting at offset
in this span
. Contains count
elements.
Remarks
A template version of this function is available that checks the count at compile time, which preserves information about the span
by returning a span
of fixed extent.
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
cout << "mySpan.subspan(1,2): ";
for (auto& i : mySpan.subspan(1,2))
{
cout << i;
}
cout << "\nmySpan.subspan<1,2>: ";
for (auto& i : mySpan.subspan<1,2>())
{
cout << i;
}
cout << "\nmySpan.subspan<1>: ";
for (auto& i : mySpan.subspan<1>)
{
cout << i;
}
}
mySpan.subspan(1,2): 12
mySpan.subspan<1,2>: 12
mySpan.subspan<1>: 12
span::value_type
The type of the element in the span
, without const
or volatile
qualifications.
using value_type = std::remove_cv_t<T>;
Example
#include <span>
#include <iostream>
using namespace std;
int main()
{
int a[] = { 0,1,2 };
span<int> mySpan(a);
span<int>::value_type vType = mySpan[2];
cout << vType;
}
2
Deduction guides
The following deduction guides are provided for span
.
// Allows the extent to be deduced from std::array and C++ built-in arrays
template <class T, size_t Extent>
span(T (&)[Extent]) -> span<T, Extent>;
template <class T, size_t Size>
span(array<T, Size>&) -> span<T, Size>;
template <class T, size_t Size>
span(const array<T, Size>&) -> span<const T, Size>;
// Allows the element type to be deduced from the iterator and the end of the span.
// The iterator must be contiguous
template <contiguous_iterator It, class End>
span(It, End) -> span<remove_reference_t<iter_reference_t<It>>>;
// Allows the element type to be deduced from a range.
// The range must be contiguous
template <ranges::contiguous_range Rng>
span(Rng &&) -> span<remove_reference_t<ranges::range_reference_t<Rng>>>;