std:: contiguous_iterator
|
Определено в заголовке
<iterator>
|
||
|
template
<
class
I
>
concept contiguous_iterator
=
|
(начиная с C++20) | |
Концепт
contiguous_iterator
расширяет
random_access_iterator
, предоставляя гарантию, что обозначенные элементы хранятся в памяти непрерывно.
|
Для итератора
i
типа, который моделирует
Это означает, что программа не может полагаться на любые побочные эффекты разыменования, инкремента или декремента contiguous iterator'а i , потому что функции стандартной библиотеки могут работать с указателями, полученными через std:: to_address ( i ) вместо работы непосредственно с i . |
(начиная с C++26) |
Содержание |
Определение концепции итератора
Определение этой концепции задаётся с помощью экспозиционно-ограниченного псевдонима шаблона /*ITER_CONCEPT*/ .
Чтобы определить /*ITER_CONCEPT*/ < I > , пусть ITER_TRAITS < I > обозначает I , если специализация std:: iterator_traits < I > сгенерирована из первичного шаблона, или std:: iterator_traits < I > в противном случае:
- Если ITER_TRAITS < I > :: iterator_concept корректен и именует тип, /*ITER_CONCEPT*/ < I > обозначает этот тип.
- Иначе, если ITER_TRAITS < I > :: iterator_category корректен и именует тип, /*ITER_CONCEPT*/ < I > обозначает этот тип.
-
Иначе, если
std::
iterator_traits
<
I
>
сгенерирован из первичного шаблона,
/*ITER_CONCEPT*/
<
I
>
обозначает
std::random_access_iterator_tag
.
(То есть предполагается, что std:: derived_from < /*ITER_CONCEPT*/ < I > , std:: contiguous_iterator_tag > равно false .) - Иначе /*ITER_CONCEPT*/ < I > не обозначает тип и приводит к ошибке подстановки.
Семантические требования
Пусть
a
и
b
будут
разыменуемыми
итераторами, а
c
будет неразыменуемым итератором типа
I
, таким что
b
является
достижимым
из
a
, а
c
достижим из
b
, тип
I
моделирует
contiguous_iterator
только если все подразумеваемые им концепты выполнены и удовлетворены все следующие условия:
- std:: to_address ( a ) == std:: addressof ( * a ) .
- std:: to_address ( b ) == std:: to_address ( a ) + std:: iter_difference_t < I > ( b - a ) .
- std:: to_address ( c ) == std:: to_address ( a ) + std:: iter_difference_t < I > ( c - a ) .
- std:: to_address ( I { } ) является корректно определённым.
- ranges:: iter_move ( a ) имеет тот же тип, категорию значения и эффекты, что и std :: move ( * a ) .
- Если ranges:: iter_swap ( a, b ) является корректно сформированным, он имеет эффекты, эквивалентные ranges:: swap ( * a, * b ) .
Сохранение равенства
Выражения, объявленные в requires выражениях концепций стандартной библиотеки, должны быть equality-preserving (если не указано иное).
Вариации неявных выражений
Выражение requires expression , использующее выражение, которое является немодифицирующим для некоторого константного lvalue операнда, также требует неявных вариаций выражений .
Примечания
contiguous_iterator
моделируется каждым типом указателя на полный тип объекта.
Типы итераторов в стандартной библиотеке, которые должны удовлетворять требованиям
LegacyContiguousIterator
в C++17, также должны моделировать
contiguous_iterator
в C++20.
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применяется к | Поведение как опубликовано | Корректное поведение |
|---|---|---|---|
| LWG 3607 | C++20 |
contiguous_iterator
мог иметь пользовательские
ranges::iter_move и ranges::iter_swap поведения |
запрещено |
| LWG 4170 | C++20 |
пара инициализированных по умолчанию
contiguous_iterator
может не быть способна представлять пустой диапазон |
гарантировано |
Смотрите также
|
(C++20)
|
определяет, что
bidirectional_iterator
является итератором произвольного доступа, поддерживающим продвижение за константное время и индексацию
(концепт) |