std::rotate
| Definiert in Header <algorithm>
|
||
template< class ForwardIt >
ForwardIt rotate( ForwardIt first, ForwardIt middle, ForwardIt last );
|
(1) | (constexpr seit C++20) |
template< class ExecutionPolicy, class ForwardIt >
ForwardIt rotate( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt middle, ForwardIt last );
|
(2) | (seit C++17) |
std::rotate vertauscht die Elemente im Bereich [first, last) so, dass die Elemente in [first, middle) nach den Elementen in [middle, last) platziert werden, während die Ordnung der Elemente in beiden Bereichen erhalten bleibt.policy ausgeführt.true ist:
|
|
(bis C++20) |
|
|
(seit C++20) |
Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:
[first,middle)oder[middle,last)ist kein gültiger Bereich.
|
(bis C++11) |
|
(seit C++11) |
Parameter
| first, last | - | das Paar von Iteratoren, das den Bereich der zu rotierenden Elemente definiert |
| middle | - | das Element, das am Anfang des rotierten Bereichs erscheinen soll |
| policy | - | die zu verwendende Ausführungsrichtlinie |
| Typanforderungen | ||
-
ForwardIt
muss die Anforderungen von
LegacyForwardIterator
erfüllen.
|
||
Rückgabewert
Der Iterator auf das ursprünglich von * first referenzierte Element, d.h. der std:: distance ( middle, last ) te nächste Iterator von first .
Komplexität
Höchstens std:: distance ( first, last ) Vertauschungen.
Ausnahmen
Die Überladung mit einem Template-Parameter namens
ExecutionPolicy
meldet Fehler wie folgt:
-
Wenn die Ausführung einer als Teil des Algorithmus aufgerufenen Funktion eine Exception wirft und
ExecutionPolicyeiner der Standard-Policies ist, wird std::terminate aufgerufen. Für jede andereExecutionPolicyist das Verhalten implementierungsdefiniert. - Wenn der Algorithmus keinen Speicher allokieren kann, wird std::bad_alloc geworfen.
Mögliche Implementierung
Siehe auch die Implementierungen in libstdc++ , libc++ , und MSVC STL .
template<class ForwardIt> constexpr // seit C++20 ForwardIt rotate(ForwardIt first, ForwardIt middle, ForwardIt last) { if (first == middle) return last; if (middle == last) return first; ForwardIt write = first; ForwardIt next_read = first; // Leseposition für den Fall, dass "read" auf "last" trifft for (ForwardIt read = middle; read != last; ++write, ++read) { if (write == next_read) next_read = read; // verfolge, wohin "first" verschoben wurde std::iter_swap(write, read); } // rotiere die verbleibende Sequenz an die richtige Position rotate(write, next_read, last); return write; } |
Hinweise
std::rotate
weist auf gängigen Implementierungen eine bessere Effizienz auf, wenn
ForwardIt
die Anforderungen an
LegacyBidirectionalIterator
oder (noch besser)
LegacyRandomAccessIterator
erfüllt.
Implementierungen (z.B.
MSVC STL
) können Vektorisierung ermöglichen, wenn der Iteratortyp
LegacyContiguousIterator
erfüllt und das Vertauschen seines Werttyps weder nicht-triviale spezielle Memberfunktionen noch
ADL
-gefundene
swap
-Funktionen aufruft.
Beispiel
std::rotate
ist ein häufig verwendeter Baustein in vielen Algorithmen. Dieses Beispiel demonstriert
Insertion Sort
.
#include <algorithm> #include <iostream> #include <vector> auto print = [](const auto remark, const auto& v) { std::cout << remark; for (auto n : v) std::cout << n << ' '; std::cout << '\n'; }; int main() { std::vector<int> v{2, 4, 2, 0, 5, 10, 7, 3, 7, 1}; print("before sort:\t\t", v); // insertion sort for (auto i = v.begin(); i != v.end(); ++i) std::rotate(std::upper_bound(v.begin(), i, *i), i, i + 1); print("after sort:\t\t", v); // simple rotation to the left std::rotate(v.begin(), v.begin() + 1, v.end()); print("simple rotate left:\t", v); // simple rotation to the right std::rotate(v.rbegin(), v.rbegin() + 1, v.rend()); print("simple rotate right:\t", v); }
Ausgabe:
before sort: 2 4 2 0 5 10 7 3 7 1 after sort: 0 1 2 2 3 4 5 7 7 10 simple rotate left: 1 2 2 3 4 5 7 7 10 0 simple rotate right: 0 1 2 2 3 4 5 7 7 10
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| LWG 488 | C++98 | die neue Position des durch first gezeigten Elements wurde nicht zurückgegeben | zurückgegeben |
Siehe auch
| kopiert und rotiert einen Bereich von Elementen (Funktionstemplate & Algorithmus-Funktionsobjekt) | |
(C++20) |
|
(C++20) |
rotiert die Reihenfolge der Elemente in einem Bereich (Algorithmus-Funktionsobjekt) |