std::reverse_iterator
| Definiert in Header <iterator> |
||
| template< class Iter > class reverse_iterator; |
||
std::reverse_iterator ist ein Iterator-Adapter, der die Richtung eines gegebenen Iterators umkehrt, welcher mindestens ein LegacyBidirectionalIterator sein muss oder ein bidirectional_iterator modelliert(seit C++20). Anders ausgedrückt, wenn ein bidirektionaler Iterator bereitgestellt wird, erzeugt std::reverse_iterator einen neuen Iterator, der sich vom Ende zum Anfang der durch den zugrunde liegenden bidirektionalen Iterator definierten Sequenz bewegt.
Für einen Reverse-Iterator r, der aus einem Iterator i konstruiert wurde, ist die Beziehung &*r == &*(i - 1) immer true (solange r dereferenzierbar ist); somit dereferenziert ein Reverse-Iterator, der aus einem "One-Past-The-End"-Iterator konstruiert wurde, zum letzten Element einer Sequenz.
Dies ist der Iterator, der von den Memberfunktionen rbegin() und rend() der Standardbibliothekscontainer zurückgegeben wird.
Inhalt |
[edit] Verschachtelte Typen
|
(bis C++20) | ||||||||||||||||
|
(seit C++20) |
- ↑ 1.0 1.1 Die Definition wird bis C++17 von der Basis-Spezialisierung std::iterator bereitgestellt.
[edit] Datenmitglieder
| Mitglied | Beschreibung |
Iter current |
der zugrunde liegende Iterator (geschütztes Member-Objekt) |
[edit] Member-Funktionen
konstruiert einen neuen reverse_iterator(öffentliche Memberfunktion) | |
weist einen anderen reverse_iterator zu(öffentliche Memberfunktion) | |
| greift auf den zugrundeliegenden Iterator zu (öffentliche Memberfunktion) | |
| greift auf das dereferenzierte Element zu (öffentliche Memberfunktion) | |
| greift per Index auf ein Element zu (öffentliche Memberfunktion) | |
bewegt den reverse_iterator vorwärts oder rückwärts(öffentliche Memberfunktion) |
[edit] Nicht-Member-Funktionen
| vergleicht die zugrundeliegenden Iteratoren (Funktionstemplate) | |
| bewegt den Iterator vorwärts (Funktionstemplate) | |
| berechnet die Distanz zwischen zwei Iterator-Adaptoren (Funktionstemplate) | |
| (C++20) |
konvertiert das Ergebnis der Dereferenzierung des angepassten zugrunde liegenden Iterators in seinen zugehörigen rvalue-Referenztyp (Funktion) |
| (C++20) |
tauscht die Objekte, auf die von zwei angepassten zugrunde liegenden Iteratoren gezeigt wird (Funktionstemplate) |
| (C++14) |
erstellt einen std::reverse_iterator vom Argument abgeleiteten Typ (Funktionsvorlage) |
[edit] Hilfsschablonen
| template< class Iterator1, class Iterator2 > requires (!std::sized_sentinel_for<Iterator1, Iterator2>) |
(seit C++20) | |
Diese partielle Spezialisierung von std::disable_sized_sentinel_for verhindert, dass Spezialisierungen von reverse_iterator sized_sentinel_for erfüllen, wenn ihre zugrunde liegenden Iteratoren das Konzept nicht erfüllen.
[edit] Mögliche Implementierung
Nachfolgend finden Sie eine Teilimplementierung, die sich auf die Art und Weise konzentriert, wie der innere Iterator gespeichert wird, und std::prev nur dann aufruft, wenn der Inhalt über operator* abgerufen wird.
template<class It> class reverse_iterator { protected: It current = It(); public: reverse_iterator() = default; constexpr explicit reverse_iterator(It itr) : current(itr) {} template<class U> requires (!std::is_same_v<U, It> && std::convertible_to<const U&, It>) constexpr explicit reverse_iterator(const U& other) : current(other.base()) {} constexpr decltype(auto) operator*() const { return *std::prev(current); // <== returns the content of prev } constexpr reverse_iterator& operator++() { --current; return *this; } constexpr reverse_iterator operator++(int) { auto tmp = *this; ++(*this); return tmp; } constexpr reverse_iterator& operator--() { ++current; return *this; } constexpr reverse_iterator operator--(int) { auto tmp = *this; --(*this); return tmp; } constexpr It base() const { return current; } // Other member functions, friend functions, and member typedefs are not shown here. }; |
[edit] Anmerkungen
std::reverse_iterator funktioniert nicht mit Iteratoren, deren Dereferenzierung eine Referenz auf ein Member von *this zurückgibt (sogenannte "stashing iterators"). Ein Beispiel für einen "stashing iterator" ist der MSVC STL's std::filesystem::path::iterator.
[edit] Beispiel
#include <cstddef> #include <iostream> #include <iterator> template<typename T, std::size_t SIZE> class Stack { T arr[SIZE]; std::size_t pos = 0; public: T pop() { return arr[--pos]; } Stack& push(const T& t) { arr[pos++] = t; return *this; } // we wish that looping on Stack would be in LIFO order // thus we use std::reverse_iterator as an adaptor to existing iterators // (which are in this case the simple pointers: [arr, arr + pos) auto begin() { return std::reverse_iterator(arr + pos); } auto end() { return std::reverse_iterator(arr); } }; int main() { Stack<int, 8> s; s.push(5).push(15).push(25).push(35); for (int val : s) std::cout << val << ' '; std::cout << '\n'; }
Ausgabe
35 25 15 5
[edit] Siehe auch
| (C++14) |
erstellt einen std::reverse_iterator vom Argument abgeleiteten Typ (Funktionsvorlage) |
| (veraltet in C++17) |
Basisklasse zur Vereinfachung der Definition der erforderlichen Typen für einfache Iteratoren (Klassenschablone) |