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)
Definiert im Header <iterator>
template < class I >

concept 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 > &&
requires ( 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 >> ;

} ;
(seit C++20)

Das Konzept random_access_iterator verfeinert bidirectional_iterator durch Hinzufügen von Unterstützung für konstante Zeit-Vorwärtsbewegung mit den Operatoren += , + , -= , und - , konstanter Zeit-Berechnung der Distanz mit - , und Array-Notation mit Indexierung [] .

Inhaltsverzeichnis

Iterator-Konzeptbestimmung

Die Definition dieses Konzepts wird über einen nur zur Darstellung dienenden Alias-Template /*ITER_CONCEPT*/ spezifiziert.

Um /*ITER_CONCEPT*/ < I > zu bestimmen, sei ITER_TRAITS < I > definiert als I falls die Spezialisierung std:: iterator_traits < I > von der Primärvorlage generiert wird, andernfalls als std:: iterator_traits < I > :

  • Falls ITER_TRAITS < I > :: iterator_concept gültig ist und einen Typ benennt, bezeichnet /*ITER_CONCEPT*/ < I > den Typ.
  • Andernfalls, falls ITER_TRAITS < I > :: iterator_category gültig ist und einen Typ benennt, bezeichnet /*ITER_CONCEPT*/ < I > den Typ.
  • Andernfalls, falls std:: iterator_traits < I > von der primären Template-Spezialisierung generiert wird, bezeichnet /*ITER_CONCEPT*/ < I > std::random_access_iterator_tag .
    (Das heißt, std:: derived_from < /*ITER_CONCEPT*/ < I > , std:: random_access_iterator_tag > wird als true angenommen.)
  • Andernfalls bezeichnet /*ITER_CONCEPT*/ < I > keinen Typ und führt zu einem Substitutionsfehler.

Semantische Anforderungen

Seien a und b gültige Iteratoren vom Typ I , sodass b von a erreichbar ist, und sei n ein Wert vom Typ std:: iter_difference_t < I > gleich b - a . std :: random_access_iterator < I > wird nur dann modelliert, wenn alle von ihm subsumierten Konzepte modelliert werden und:

  • ( a + = n ) entspricht b .
  • std:: addressof ( a + = n ) entspricht std:: addressof ( a ) . [1]
  • ( a + n ) entspricht ( a + = n ) .
  • ( a + n ) entspricht ( n + a ) .
  • Für zwei beliebige positive Ganzzahlen x und y , falls a + ( x + y ) gültig ist, dann entspricht a + ( x + y ) ( a + x ) + y .
  • a + 0 entspricht a .
  • Falls ( a + ( n - 1 ) ) gültig ist, dann entspricht -- b ( a + ( n - 1 ) ) .
  • ( b + = - n ) und ( b - = n ) entsprechen beide a .
  • std:: addressof ( b - = n ) entspricht std:: addressof ( b ) . [1]
  • ( b - n ) entspricht ( b - = n ) .
  • Falls b dereferenzierbar ist, dann ist a [ n ] gültig und entspricht * b .
  • bool ( a <= b ) ist true .
  • Jede erforderliche Operation hat konstante Zeitkomplexität.

Beachten Sie, dass std::addressof die Adresse des Iterator-Objekts zurückgibt, nicht die Adresse des Objekts, auf das der Iterator zeigt. D.h. operator+= und operator-= müssen eine Referenz auf * this zurückgeben.

Gleichheitserhaltung

Ausdrücke, die in requires expressions der Standardbibliothek-Konzepte deklariert werden, müssen equality-preserving sein (sofern nicht anders angegeben).

Implizite Ausdrucksvarianten

Ein requires -Ausdruck , der einen Ausdruck verwendet, der für einen konstanten Lvalue-Operanden nicht-modifizierend ist, erfordert ebenfalls implizite Ausdrucksvarianten .

Hinweise

Im Gegensatz zu den LegacyRandomAccessIterator -Anforderungen erfordert das random_access_iterator -Konzept nicht, dass die Dereferenzierung einen L-Wert zurückgibt.

Beispiel

Demonstriert eine mögliche Implementierung von std::distance mittels C++20-Konzepten.

#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);
}

Siehe auch

spezifiziert, dass ein forward_iterator ein bidirektionaler Iterator ist, der Rückwärtsbewegung unterstützt
(Konzept)
spezifiziert, dass ein random_access_iterator ein zusammenhängender Iterator ist, der auf im Speicher zusammenhängende Elemente verweist
(Konzept)