std::ranges::prev
| Definiert in Header <iterator> |
||
| Aufruf-Signatur |
||
| template< std::bidirectional_iterator I > constexpr I prev( I i ); |
(1) | (seit C++20) |
| template< std::bidirectional_iterator I > constexpr I prev( I i, std::iter_difference_t<I> n ); |
(2) | (seit C++20) |
| template< std::bidirectional_iterator I > constexpr I prev( I i, std::iter_difference_t<I> n, I bound ); |
(3) | (seit C++20) |
Gibt den n-ten Vorgänger des Iterators i zurück.
Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithmus-Funktionsobjekte (informell als niebloids bekannt), d.h.
- Können explizite Template-Argumentlisten bei keinem von ihnen angegeben werden.
- Keiner von ihnen ist für Argument-abhängige Suche sichtbar.
- Wenn einer von ihnen durch normale unqualifizierte Suche als Name links vom Funktionsaufrufoperator gefunden wird, wird die Argument-abhängige Suche unterdrückt.
Inhalt |
[bearbeiten] Parameter
| i | - | ein Iterator |
| n | - | Anzahl der Elemente, die i zurückgehen soll |
| bound | - | Iterator, der den Anfang des Bereichs bezeichnet, auf den i zeigt |
[bearbeiten] Rückgabewert
[bearbeiten] Komplexität
[bearbeiten] Mögliche Implementierung
struct prev_fn { template<std::bidirectional_iterator I> constexpr I operator()(I i) const { --i; return i; } template<std::bidirectional_iterator I> constexpr I operator()(I i, std::iter_difference_t<I> n) const { ranges::advance(i, -n); return i; } template<std::bidirectional_iterator I> constexpr I operator()(I i, std::iter_difference_t<I> n, I bound) const { ranges::advance(i, -n, bound); return i; } }; inline constexpr auto prev = prev_fn(); |
[bearbeiten] Hinweise
Obwohl der Ausdruck --r.end() oft für Container kompiliert, ist dies nicht garantiert: r.end() ist ein rvalue-Ausdruck, und es gibt keine Iterator-Anforderung, die festlegt, dass die Dekrementierung eines rvalues garantiert funktioniert. Insbesondere, wenn Iteratoren als Zeiger implementiert sind oder ihr operator-- als lvalue-referenziert qualifiziert ist, kompiliert --r.end() nicht, während ranges::prev(r.end()) dies tut.
Dies wird weiter verschärft durch Bereiche, die ranges::common_range nicht modellieren. Beispielsweise hat für einige zugrunde liegende Bereiche ranges::transform_view::end nicht denselben Rückgabetyp wie ranges::transform_view::begin, und daher kompiliert --r.end() nicht. Dies ist nichts, womit ranges::prev helfen kann, aber es gibt Workarounds.
[bearbeiten] Beispiel
#include <iostream> #include <iterator> #include <vector> int main() { std::vector<int> v{3, 1, 4}; auto pv = std::ranges::prev(v.end(), 2); std::cout << *pv << '\n'; pv = std::ranges::prev(pv, 42, v.begin()); std::cout << *pv << '\n'; }
Ausgabe
1 3
[bearbeiten] Siehe auch
| (C++20) |
inkrementiert einen Iterator um eine gegebene Distanz oder zu einer Grenze (Algorithmus-Funktionsobjekt) |
| (C++20) |
bewegt einen Iterator um die angegebene Distanz vorwärts oder zu einer gegebenen Grenze (Algorithmus-Funktionsobjekt) |
| (C++11) |
dekrementiert einen Iterator (Funktionsvorlage) |