Namespaces
Variants

std:: random_access_iterator

From cppreference.net
Iterator library
Iterator concepts
random_access_iterator
(C++20)


Iterator primitives
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Range access
(C++11) (C++14)
(C++14) (C++14)
(C++11) (C++14)
(C++14) (C++14)
(C++17) (C++20)
(C++17)
(C++17)
Definido en el encabezado <iterator>
template < class I >

concepto random_access_iterator =
std:: bidirectional_iterator < I > &&
std:: derived_from < /*ITER_CONCEPT*/ < I > , std:: random_access_iterator_tag > &&
std:: totally_ordered < I > &&
std:: sized_sentinel_for < I, I > &&
requiere ( I i, const I j, const std:: iter_difference_t < I > n ) {
{ i + = n } - > std:: same_as < I & > ;
{ j + n } - > std:: same_as < I > ;
{ n + j } - > std:: same_as < I > ;
{ i - = n } - > std:: same_as < I & > ;
{ j - n } - > std:: same_as < I > ;
{ j [ n ] } - > std:: same_as < std:: iter_reference_t < I >> ;

} ;
(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 x y y , 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

especifica que un forward_iterator es un iterador bidireccional, que admite movimiento hacia atrás
(concepto)
especifica que un random_access_iterator es un iterador contiguo, que hace referencia a elementos contiguos en memoria
(concepto)