std:: random_access_iterator
|
Definido en el encabezado
<iterator>
|
||
|
template
<
class
I
>
concepto random_access_iterator
=
|
(desde C++20) | |
El concepto
random_access_iterator
refina
bidirectional_iterator
añadiendo soporte para avance en tiempo constante con los operadores
+=
,
+
,
-=
, y
-
, cálculo de distancia en tiempo constante con
-
, y notación de arreglo con subíndices
[]
.
Contenidos |
Determinación del concepto de iterador
La definición de este concepto se especifica mediante un alias de plantilla solo para exposición /*ITER_CONCEPT*/ .
Para determinar /*ITER_CONCEPT*/ < I > , sea ITER_TRAITS < I > igual a I si la especialización std:: iterator_traits < I > está generada desde la plantilla principal, o std:: iterator_traits < I > en caso contrario:
- Si ITER_TRAITS < I > :: iterator_concept es válido y nombra un tipo, /*ITER_CONCEPT*/ < I > denota el tipo.
- De lo contrario, si ITER_TRAITS < I > :: iterator_category es válido y nombra un tipo, /*ITER_CONCEPT*/ < I > denota el tipo.
-
De lo contrario, si
std::
iterator_traits
<
I
>
se genera desde la plantilla principal,
/*ITER_CONCEPT*/
<
I
>
denota
std::random_access_iterator_tag
.
(Es decir, std:: derived_from < /*ITER_CONCEPT*/ < I > , std:: random_access_iterator_tag > se asume que es true .) - De lo contrario, /*ITER_CONCEPT*/ < I > no denota un tipo y resulta en un fallo de sustitución.
Requisitos semánticos
Sean
a
y
b
iteradores válidos de tipo
I
tales que
b
es alcanzable desde
a
, y sea
n
un valor de tipo
std::
iter_difference_t
<
I
>
igual a
b
-
a
.
std
::
random_access_iterator
<
I
>
se modela solo si todos los conceptos que subsume están modelados y:
- ( a + = n ) es igual a b .
- std:: addressof ( a + = n ) es igual a std:: addressof ( a ) . [1]
- ( a + n ) es igual a ( a + = n ) .
- ( a + n ) es igual a ( n + a ) .
-
Para cualesquiera dos enteros positivos
xyy, si a + ( x + y ) es válido, entonces a + ( x + y ) es igual a ( a + x ) + y . - a + 0 es igual a a .
- Si ( a + ( n - 1 ) ) es válido, entonces -- b es igual a ( a + ( n - 1 ) ) .
- ( b + = - n ) y ( b - = n ) son ambos iguales a a .
- std:: addressof ( b - = n ) es igual a std:: addressof ( b ) . [1]
- ( b - n ) es igual a ( b - = n ) .
- Si b es dereferenciable, entonces a [ n ] es válido y es igual a * b .
- bool ( a <= b ) es true .
- Cada operación requerida tiene complejidad temporal constante.
Tenga en cuenta que
std::addressof
devuelve la dirección del objeto iterador, no la dirección del objeto al que apunta el iterador. Es decir,
operator+=
y
operator-=
deben devolver una referencia a
*
this
.
Preservación de la igualdad
Las expresiones declaradas en las requires expressions de los conceptos de la biblioteca estándar deben ser equality-preserving (excepto cuando se indique lo contrario).
Variaciones de expresión implícita
Una requires expresión que utiliza una expresión que no es modificadora para algún operando constante lvalue también requiere variaciones de expresión implícitas .
Notas
A diferencia de los
LegacyRandomAccessIterator
requirements, el concepto
random_access_iterator
no requiere que la desreferenciación retorne un lvalue.
Ejemplo
Demuestra una posible implementación de std::distance mediante conceptos de 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); }
Véase también
|
(C++20)
|
especifica que un
forward_iterator
es un iterador bidireccional, que admite movimiento hacia atrás
(concepto) |
|
(C++20)
|
especifica que un
random_access_iterator
es un iterador contiguo, que hace referencia a elementos contiguos en memoria
(concepto) |