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 не квалифицируется как константа.
Все требования к типам итераторов для Container также применяются к типу iterator для span.
Элемент константа
<tbody> </tbody> static constexpr std::size_t extent = Extent; |
(начиная с C++20) | |
Функции-элементы
(C++20) |
создаёт span (public функция-элемент) |
(C++20) |
присваивает span (public функция-элемент) |
Итераторы | |
(C++11) |
возвращает итератор на начало (public функция-элемент) |
(C++11) |
возвращает итератор на конец (public функция-элемент) |
(C++11) |
возвращает обратный итератор на начало (public функция-элемент) |
(C++11) |
возвращает обратный итератор на конец (public функция-элемент) |
Доступ к элементам | |
(C++20) |
предоставляет доступ к первому элементу (public функция-элемент) |
(C++20) |
предоставляет доступ к последнему элементу (public функция-элемент) |
(C++20) |
предоставляет доступ к элементу последовательности (public функция-элемент) |
(C++20) |
возвращает указатель на начало последовательности элементов (public функция-элемент) |
Наблюдатели | |
(C++20) |
возвращает количество элементов в последовательности (public функция-элемент) |
(C++20) |
возвращает размер последовательности в байтах (public функция-элемент) |
(C++20) |
проверяет, является ли последовательность пустой (public функция-элемент) |
Подпредставления | |
(C++20) |
возвращает поддиапазон, содержащий первые N элементов последовательности (public функция-элемент) |
(C++20) |
возвращает поддиапазон, содержащий последние N элементов последовательности (public функция-элемент) |
(C++20) |
возвращает поддиапазон (public функция-элемент) |
Функции, не являющиеся элементами
(C++20) |
преобразует span в представление, состоящее из образующих его байтов (шаблон функции) |
Константа, не являющаяся элементом
(C++20) |
константа типа size_t, означающая, что span имеет динамический размер (константа) |
Вспомогательные шаблоны
<tbody> </tbody> template<class T, std::size_t Extent> inline constexpr bool ranges::enable_borrowed_range<std::span<T, Extent>> = true; |
||
Эта специализация ranges::enable_borrowed_range заставляет span соответствовать borrowed_range.
template<class T, std::size_t Extent> inline constexpr bool ranges::enable_view<std::span<T, Extent>> = Extent == 0 || Extent == dynamic_extent; |
||
Эта специализация ranges::enable_view заставляет span соответствовать view.
Принципы вывода
Примечание
Специализации std::span уже являются тривиально копируемыми типами во всех существующих реализациях, даже до формального требования, введённого в C++23.
| Макрос Тестирования функциональности | Значение | Стандарт | Функциональность |
|---|---|---|---|
__cpp_lib_span |
202002L |
(C++20) | std::span
|
Пример
В примере используется 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 print(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 };
for (std::size_t offset{}; ; ++offset) {
static constexpr std::size_t width{6};
auto s = slide(std::span{a}, offset, width);
if (s.empty())
break;
print(s);
}
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++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| WG не указан | C++20 | span ненулевых статических размеров не были view
|
default_initializable не требуют
|
Смотрите также
(C++23) |
многомерное представление массива без владения (шаблон класса) |
(C++20) |
объединяет пару итератор-ограничитель в view (шаблон класса) |
(C++11) |
создаёт временный массив в списке инициализации, а затем ссылается на него (шаблон класса) |
(C++17) |
строковое представление только для чтения (шаблон класса) |