std::span
Определён в заголовке <span> | ||
|---|---|---|
template<
class T,
std::size_t Extent = std::dynamic_extent
> class span;
| (начиная с C++20) |
Шаблон класса span описывает объект, который может ссылаться на непрерывную последовательность объектов, первый элемент которой находится в позиции ноль. span может иметь статический размер, в этом случае число элементов последовательности известно во время компиляции и закодировано в типе, либо динамический размер.
Для span s указатели, итераторы и ссылки на элементы s становятся недействительными, если операция делает недействительным указатель в диапазоне [s.data(), s.data() + s.size()).
| Каждая специализация | (начиная с C++23) |
Параметры шаблона
| T | - | тип элемента; должен быть полным типом объекта, не являющимся абстрактным типом класса |
| Extent | - | число элементов в последовательности или std::dynamic_extent для динамического размера |
Вложенные типы
| Тип | Определение |
|---|---|
element_type |
T |
value_type | std::remove_cv_t<T> |
size_type |
std::size_t |
difference_type |
std::ptrdiff_t |
pointer | T* |
const_pointer | constT* |
reference | T& |
const_reference | constT& |
iterator[1] | определяемый реализацией LegacyRandomAccessIterator, ConstexprIterator и contiguous_iterator, чей value_type равен value_type |
const_iterator (начиная с C++23) | std::const_iterator<iterator> |
reverse_iterator | std::reverse_iterator<iterator> |
const_reverse_iterator (начиная с C++23) | std::const_iterator<reverse_iterator> |
-
iteratorявляется изменяемым итератором, еслиTне имеет квалификатора const.
К типу iterator для span также применяются все требования к типам итераторов контейнера.
Члены данных
| Член | Описание |
|---|---|
|
extent
[static] |
Extent (общедоступная статическая константа-член) |
pointer data_ | указатель на базовую последовательность (член-объект только для описания*) |
size_type size_ (присутствует только при динамическом размере) | число элементов (член-объект только для описания*) |
Функции-члены
создаёт span (общедоступная функция-член) |
|
присваивает span (общедоступная функция-член) |
|
|
(деструктор)
(объявляется неявно) | уничтожает span (общедоступная функция-член) |
Итераторы |
|
|
(C++23) | возвращает итератор на начало (общедоступная функция-член) |
|
(C++23) | возвращает итератор на конец (общедоступная функция-член) |
|
(C++23) | возвращает обратный итератор на начало (общедоступная функция-член) |
|
(C++23) | возвращает обратный итератор на конец (общедоступная функция-член) |
Доступ к элементам |
|
| доступ к первому элементу (общедоступная функция-член) |
|
| доступ к последнему элементу (общедоступная функция-член) |
|
|
(C++26) | доступ к указанному элементу с проверкой границ (общедоступная функция-член) |
| доступ к указанному элементу (общедоступная функция-член) |
|
| прямой доступ к базовому непрерывному хранилищу (общедоступная функция-член) |
|
Наблюдатели |
|
| возвращает число элементов (общедоступная функция-член) |
|
| возвращает размер последовательности в байтах (общедоступная функция-член) |
|
| проверяет, пуста ли последовательность (общедоступная функция-член) |
|
Подпредставления |
|
получает поддиапазон, состоящий из первых N элементов последовательности (общедоступная функция-член) |
|
получает поддиапазон, состоящий из последних N элементов последовательности (общедоступная функция-член) |
|
| получает поддиапазон (общедоступная функция-член) |
|
Функции, не являющиеся членами
|
(C++20) | преобразует span в представление его базовых байтов (шаблон функции) |
Вспомогательная константа
|
(C++20) | константа типа std::size_t, указывающая, что span имеет динамический размер (константа) |
Вспомогательные шаблоны
template< class T, std::size_t Extent > constexpr bool ranges::enable_borrowed_range<std::span<T, Extent>> = true; | (начиная с C++20) |
Эта специализация ranges::enable_borrowed_range позволяет span удовлетворять требованиям borrowed_range.
template< class T, std::size_t Extent > constexpr bool ranges::enable_view<std::span<T, Extent>> = true; | (начиная с C++20) |
Эта специализация ranges::enable_view позволяет span удовлетворять требованиям view.
Направляющие вывода
Примечания
Специализации std::span уже являются тривиально копируемыми типами во всех существующих реализациях, даже до введения формального требования в C++23.
| Макрос проверки функциональности | Значение | Стандарт | Функциональность |
|---|---|---|---|
__cpp_lib_span | 202002L | (C++20) |
std::span |
202311L | (C++26) |
std::span::at |
Пример
В примере std::span используется для реализации нескольких алгоритмов для непрерывных диапазонов.
#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);
}
template<class T, std::size_t N, std::size_t M>
constexpr bool starts_with(std::span<T, N> data, std::span<T, M> prefix)
{
return data.size() >= prefix.size()
&& std::equal(prefix.begin(), prefix.end(), data.begin());
}
template<class T, std::size_t N, std::size_t M>
constexpr bool ends_with(std::span<T, N> data, std::span<T, M> suffix)
{
return data.size() >= suffix.size()
&& std::equal(data.end() - suffix.size(), data.end(),
suffix.end() - suffix.size());
}
template<class T, std::size_t N, std::size_t M>
constexpr bool contains(std::span<T, N> span, std::span<T, M> sub)
{
return std::ranges::search(span, sub).begin() != span.end();
}
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 int b[]{8, 7, 6};
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;
static_assert(""
&& starts_with(std::span{a}, std::span{a, 4})
&& starts_with(std::span{a + 1, 4}, std::span{a + 1, 3})
&& !starts_with(std::span{a}, std::span{b})
&& !starts_with(std::span{a, 8}, std::span{a + 1, 3})
&& ends_with(std::span{a}, std::span{a + 6, 3})
&& !ends_with(std::span{a}, std::span{a + 6, 2})
&& contains(std::span{a}, std::span{a + 1, 4})
&& !contains(std::span{a, 8}, std::span{a, 9})
);
}
Вывод:
0 1 2 3 4 5 1 2 3 4 5 6 2 3 4 5 6 7 3 4 5 6 7 8
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.
| Отчёт об ошибке | Применён к | Поведение согласно опубликованной версии | Корректное поведение |
|---|---|---|---|
| LWG 3203 | C++20 | не было ясно, в каких случаях указатели, итераторы и ссылки на элементы span становятся недействительными | прояснено |
| LWG 3903 | C++20 | объявление деструктора span было излишним | объявление удалено |
| P2325R3 | C++20 | span с ненулевым статическим размером не являлся view | любой span является view |
См. также
|
(C++23) | невладеющее многомерное представление массива (шаблон класса) |
|
(C++20) | объединяет пару «итератор — sentinel» в view (шаблон класса) |
|
(C++11) | ссылается на временный массив, созданный при инициализации списком (шаблон класса) |
|
(C++17) | представление строки только для чтения (шаблон класса) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/container/span