std::span
Определено в заголовке <span> | ||
|---|---|---|
template<
class T,
std::size_t Extent = std::dynamic_extent
> class span;
| (с C++20) |
Шаблон класса span описывает объект, который может ссылаться на непрерывную последовательность объектов, причём первый элемент последовательности находится в позиции ноль. span может иметь статический объём, в таком случае количество элементов в последовательности известно на этапе компиляции и закодировано в типе, или динамический объём.
Если у span динамический объём, типичная реализация содержит два члена: указатель на T и размер. span со статическим объёмом может содержать только один член: указатель на T.
| Любая специализация | (с 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 | const T* |
reference | T& |
const_reference | const T& |
iterator | определяемый реализацией 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.
Все требования к типам итераторов контейнера Container применимы и к типу iterator span.
Постоянные члены
static constexpr std::size_t extent = Extent; | (с C++20) |
Члены-функции
создаёт 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 > inline 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 > inline 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 |
|
__cpp_lib_span_initializer_list | 202311L | (C++26) | Создание std::span из std::initializer_list |
Пример
Пример использует 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++.
| DR | Применено к | Поведение, как опубликовано | Правильное поведение |
|---|---|---|---|
| LWG 3903 | C++20 | объявление деструктора span было лишним | удалено объявление |
| P2325R3 | C++20 | span с ненулевыми статическими размерами не являлся view | любой span является view |
См. также
|
(C++23) | многомерный невладеющий массив-вью (шаблон класса) |
|
(C++20) | объединяет пару итератор-предел в view (шаблон класса) |
|
(C++11) | создаёт временный массив в инициализации списком, а затем ссылается на него (шаблон класса) |
|
(C++17) | просмотр только для чтения строки (шаблон класса) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/container/span