std:: random_access_iterator
|
Défini dans l'en-tête
<iterator>
|
||
|
template
<
class
I
>
concept random_access_iterator
=
|
(depuis C++20) | |
Le concept
random_access_iterator
affine
bidirectional_iterator
en ajoutant la prise en charge de l'avancement en temps constant avec les opérateurs
+=
,
+
,
-=
, et
-
, le calcul en temps constant de la distance avec
-
, et la notation de tableau avec l'indexation
[]
.
Table des matières |
Détermination du concept d'itérateur
La définition de ce concept est spécifiée via un alias de modèle exposition-seulement /*ITER_CONCEPT*/ .
Afin de déterminer /*ITER_CONCEPT*/ < I > , soit ITER_TRAITS < I > dénotant I si la spécialisation std:: iterator_traits < I > est générée à partir du modèle primaire, ou std:: iterator_traits < I > sinon :
- Si ITER_TRAITS < I > :: iterator_concept est valide et désigne un type, /*ITER_CONCEPT*/ < I > désigne ce type.
- Sinon, si ITER_TRAITS < I > :: iterator_category est valide et désigne un type, /*ITER_CONCEPT*/ < I > désigne ce type.
-
Sinon, si
std::
iterator_traits
<
I
>
est généré à partir du modèle primaire,
/*ITER_CONCEPT*/
<
I
>
désigne
std::random_access_iterator_tag
.
(C'est-à-dire que std:: derived_from < /*ITER_CONCEPT*/ < I > , std:: random_access_iterator_tag > est supposé être true .) - Sinon, /*ITER_CONCEPT*/ < I > ne désigne pas un type et entraîne un échec de substitution.
Exigences sémantiques
Soient
a
et
b
des itérateurs valides de type
I
tels que
b
soit accessible depuis
a
, et soit
n
une valeur de type
std::
iter_difference_t
<
I
>
égale à
b
-
a
.
std
::
random_access_iterator
<
I
>
est modélisé seulement si tous les concepts qu'il subsume sont modélisés et :
- ( a + = n ) est égal à b .
- std:: addressof ( a + = n ) est égal à std:: addressof ( a ) . [1]
- ( a + n ) est égal à ( a + = n ) .
- ( a + n ) est égal à ( n + a ) .
-
Pour deux entiers positifs quelconques
xety, si a + ( x + y ) est valide, alors a + ( x + y ) est égal à ( a + x ) + y . - a + 0 est égal à a .
- Si ( a + ( n - 1 ) ) est valide, alors -- b est égal à ( a + ( n - 1 ) ) .
- ( b + = - n ) et ( b - = n ) sont tous deux égaux à a .
- std:: addressof ( b - = n ) est égal à std:: addressof ( b ) . [1]
- ( b - n ) est égal à ( b - = n ) .
- Si b est déréférençable, alors a [ n ] est valide et est égal à * b .
- bool ( a <= b ) est true .
- Toute opération requise a une complexité temporelle constante.
Notez que
std::addressof
renvoie l'adresse de l'objet itérateur, et non l'adresse de l'objet pointé par l'itérateur. Autrement dit,
operator+=
et
operator-=
doivent renvoyer une référence à
*
this
.
Préservation de l'égalité
Les expressions déclarées dans les requires expressions des concepts de la bibliothèque standard doivent être equality-preserving (sauf indication contraire).
Variations d'expression implicite
Une requires expression qui utilise une expression non modifiante pour un opérande constant lvalue requiert également les variations d'expression implicites .
Notes
Contrairement aux
exigences LegacyRandomAccessIterator
, le concept
random_access_iterator
n'exige pas que le déréférencement retourne une lvalue.
Exemple
Démontre une implémentation possible de std::distance via les concepts C++20.
#include <iterator> namespace cxx20 { template<std::input_or_output_iterator Iter> constexpr std::iter_difference_t<Iter> distance(Iter first, Iter last) { if constexpr(std::random_access_iterator<Iter>) return last - first; else { std::iter_difference_t<Iter> result{}; for (; first != last; ++first) ++result; return result; } } } int main() { static constexpr auto il = {3, 1, 4}; static_assert(std::random_access_iterator<decltype(il.begin())> && cxx20::distance(il.begin(), il.end()) == 3 && cxx20::distance(il.end(), il.begin()) == -3); }
Voir aussi
|
(C++20)
|
spécifie qu'un
forward_iterator
est un itérateur bidirectionnel, prenant en charge le déplacement vers l'arrière
(concept) |
|
(C++20)
|
spécifie qu'un
random_access_iterator
est un itérateur contigu, faisant référence à des éléments contigus en mémoire
(concept) |