std::random_access_iterator
| Definiert in Header <iterator> |
||
| template< class I > concept random_access_iterator = |
(seit C++20) | |
Das Konzept random_access_iterator verfeinert bidirectional_iterator durch Hinzufügen der Unterstützung für konstante Zeitfortschritte mit den Operatoren +=, +, -= und -, konstante Zeitberechnung der Distanz mit - und Array-Notation mit der Subskriptierung [].
Inhalt |
[bearbeiten] Bestimmung des Iterator-Konzepts
Die Definition dieses Konzepts wird über ein expositions-only-Alias-Template /*ITER_CONCEPT*/ spezifiziert.
Um /*ITER_CONCEPT*/<I> zu bestimmen, bezeichne ITER_TRAITS<I> I, wenn die Spezialisierung std::iterator_traits<I> aus der Primärvorlage generiert wird, oder std::iterator_traits<I> andernfalls.
- Wenn ITER_TRAITS<I>::iterator_concept gültig ist und einen Typ benennt, bezeichnet /*ITER_CONCEPT*/<I> diesen Typ.
- Andernfalls, wenn ITER_TRAITS<I>::iterator_category gültig ist und einen Typ benennt, bezeichnet /*ITER_CONCEPT*/<I> diesen Typ.
- Andernfalls, wenn std::iterator_traits<I> aus der primären Vorlage generiert wird, bezeichnet /*ITER_CONCEPT*/<I> std::random_access_iterator_tag.
- Andernfalls bezeichnet /*ITER_CONCEPT*/<I> keinen Typ und führt zu einem Substitutionsfehler.
[edit] Semantische Anforderungen
Seien a und b gültige Iteratoren des Typs I, so dass 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 umfassten Konzepte modelliert werden und
- (a += n) gleich b ist.
- std::addressof(a += n) ist gleich std::addressof(a). [1]
- (a + n) ist gleich (a += n).
- (a + n) ist gleich (n + a).
- Für zwei positive ganze Zahlen
xundygilt: Wenn a + (x + y) gültig ist, dann ist a + (x + y) gleich (a + x) + y. - a + 0 ist gleich a.
- Wenn (a + (n - 1)) gültig ist, dann ist --b gleich (a + (n - 1)).
- (b += -n) und (b -= n) sind beide gleich a.
- std::addressof(b -= n) ist gleich std::addressof(b). [1]
- (b - n) ist gleich (b -= n).
- Wenn b dereferenzierbar ist, dann ist a[n] gültig und gleich *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.
[bearbeiten] Gleichheitserhaltung
Ausdrücke, die in requires-Ausdrücken der Standardbibliothekskonzepte deklariert sind, müssen gleichheitserhaltend sein (sofern nicht anders angegeben).
[bearbeiten] Implizite Ausdrucksvariationen
Ein requires-Ausdruck, der einen Ausdruck verwendet, der für einen konstanten Lvalue-Operanden nicht-modifizierend ist, erfordert ebenfalls implizite Ausdrucksvariationen.
[edit] Anmerkungen
Im Gegensatz zu den LegacyRandomAccessIterator-Anforderungen erfordert das Konzept random_access_iterator nicht, dass die Dereferenzierung ein lvalue zurückgibt.
[edit] 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); }
[edit] Siehe auch
| (C++20) |
spezifiziert, dass ein forward_iterator ein bidirektionaler Iterator ist, der die Rückwärtsbewegung unterstützt(Konzept) |
| (C++20) |
gibt an, dass ein random_access_iterator ein zusammenhängender Iterator ist, der sich auf Elemente bezieht, die im Speicher zusammenhängend sind(Konzept) |