std::shift_left, std::shift_right
Aus de.cppreference.net
< cpp | Algorithmus
| Definiert in Header <algorithm>
|
||
template< class ForwardIt >
constexpr ForwardIt shift_left( ForwardIt first, ForwardIt last,
typename std::iterator_traits<ForwardIt>::
difference_type n );
|
(1) | (seit C++20) |
template< class ExecutionPolicy, class ForwardIt >
ForwardIt shift_left( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last,
typename std::iterator_traits<ForwardIt>::
difference_type n );
|
(2) | (seit C++20) |
template< class ForwardIt >
constexpr ForwardIt shift_right( ForwardIt first, ForwardIt last,
typename std::iterator_traits<ForwardIt>::
difference_type n );
|
(3) | (seit C++20) |
template< class ExecutionPolicy, class ForwardIt >
ForwardIt shift_right( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last,
typename std::iterator_traits<ForwardIt>::
difference_type n );
|
(4) | (seit C++20) |
Verschiebt die Elemente im Bereich [first, last) um n Positionen.
1) Verschiebt die Elemente in Richtung des Anfangs des Bereichs.
- Wenn
n == 0 || n >= last - first, hat dies keine Auswirkungen. - Andernfalls verschiebt für jede ganze Zahl
iin[0,last - first - n)das Element, das sich ursprünglich an Positionfirst + n + ibefand, an Positionfirst + i.
Die Verschiebungen werden in aufsteigender Reihenfolge von
i beginnend mit 0 durchgeführt.3) Verschiebt die Elemente in Richtung des Endes des Bereichs.
- Wenn
n == 0 || n >= last - first, hat dies keine Auswirkungen. - Andernfalls verschiebt für jede ganze Zahl
iin[0,last - first - n)das Element, das sich ursprünglich an Positionfirst + ibefand, an Positionfirst + n + i.
Wenn
ForwardIt die Anforderungen von LegacyBidirectionalIterator erfüllt, werden die Verschiebungen in absteigender Reihenfolge von i beginnend mit last - first - n - 1 durchgeführt.2,4) Gleich wie (1) bzw. (3), jedoch ausgeführt gemäß
policy und die Verschiebungen können in beliebiger Reihenfolge erfolgen. Diese Überladungen nehmen nur an der Überladungsauflösung teil, wenn
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> ist true.Elemente, die sich im ursprünglichen Bereich, aber nicht im neuen Bereich befinden, bleiben in einem gültigen, aber nicht spezifizierten Zustand.
Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:
n >= 0ist nichttrue.- Der Typ von
*firstist nicht MoveAssignable. - Für
shift_rightistForwardItweder LegacyBidirectionalIterator noch ValueSwappable.
Parameter
| first, last | - | das Paar von Iteratoren, das den Bereich der zu verschiebenden Elemente definiert |
| n | - | die Anzahl der Positionen, um die verschoben werden soll |
| policy | - | die zu verwendende Ausführungsrichtlinie |
| Typanforderungen | ||
-
ForwardIt
muss die Anforderungen von
LegacyForwardIterator
erfüllen.
|
||
Rückgabewert
1,2)
Das Ende des resultierenden Bereichs.
- Falls n kleiner ist als std:: distance ( first, last ) , wird ein Iterator zurückgegeben, der gleich std:: next ( first, ( std:: distance ( first, last ) - n ) ) ist.
- Andernfalls wird first zurückgegeben.
3,4)
Der Anfang des resultierenden Bereichs.
- Wenn n kleiner ist als std:: distance ( first, last ) , wird ein Iterator gleich std:: next ( first, n ) zurückgegeben.
- Andernfalls wird last zurückgegeben.
Komplexität
1,2)
Höchstens
std::
distance
(
first, last
)
-
n
Zuweisungen.
3,4)
Höchstens
std::
distance
(
first, last
)
-
n
Zuweisungen oder Vertauschungen.
Ausnahmen
Die Überladungen mit einem Template-Parameter namens
ExecutionPolicy
melden 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 allozieren kann, wird std::bad_alloc geworfen.
Hinweise
| Feature-Test Makro | Wert | Std | Funktion |
|---|---|---|---|
__cpp_lib_shift
|
201806L
|
(C++20) |
std::shift_left
und
std::shift_right
|
Beispiel
Diesen Code ausführen
#include <algorithm> #include <iostream> #include <string> #include <type_traits> #include <vector> struct S { int value{0}; bool specified_state{true}; S(int v = 0) : value{v} {} S(S const& rhs) = default; S(S&& rhs) { *this = std::move(rhs); } S& operator=(S const& rhs) = default; S& operator=(S&& rhs) { if (this != &rhs) { value = rhs.value; specified_state = rhs.specified_state; rhs.specified_state = false; } return *this; } }; template<typename T> std::ostream& operator<<(std::ostream& os, std::vector<T> const& v) { for (const auto& s : v) { if constexpr (std::is_same_v<T, S>) s.specified_state ? os << s.value << ' ' : os << ". "; else if constexpr (std::is_same_v<T, std::string>) os << (s.empty() ? "." : s) << ' '; else os << s << ' '; } return os; } int main() { std::cout << std::left; std::vector<S> a{1, 2, 3, 4, 5, 6, 7}; std::vector<int> b{1, 2, 3, 4, 5, 6, 7}; std::vector<std::string> c{"α", "β", "γ", "δ", "ε", "ζ", "η"}; std::cout << "vector<S> \tvector<int> \tvector<string>\n"; std::cout << a << " " << b << " " << c << '\n'; std::shift_left(begin(a), end(a), 3); std::shift_left(begin(b), end(b), 3); std::shift_left(begin(c), end(c), 3); std::cout << a << " " << b << " " << c << '\n'; std::shift_right(begin(a), end(a), 2); std::shift_right(begin(b), end(b), 2); std::shift_right(begin(c), end(c), 2); std::cout << a << " " << b << " " << c << '\n'; std::shift_left(begin(a), end(a), 8); // hat keine Wirkung: n >= last - first std::shift_left(begin(b), end(b), 8); // ditto std::shift_left(begin(c), end(c), 8); // ditto std::cout << a << " " << b << " " << c << '\n'; // std::shift_left(begin(a), end(a), -3); // UB, z.B. Segfault }
Mögliche Ausgabe:
vector<S> vector<int> vector<string> 1 2 3 4 5 6 7 1 2 3 4 5 6 7 α β γ δ ε ζ η 4 5 6 7 . . . 4 5 6 7 5 6 7 δ ε ζ η . . . . . 4 5 6 7 . 4 5 4 5 6 7 5 . . δ ε ζ η . . . 4 5 6 7 . 4 5 4 5 6 7 5 . . δ ε ζ η .
Siehe auch
(C++11) |
verschiebt einen Bereich von Elementen an eine neue Position (Funktionstemplate & Algorithmusfunktionsobjekt) |
(C++20) |
|
(C++11) |
verschiebt einen Bereich von Elementen in umgekehrter Reihenfolge an eine neue Position (Funktionstemplate & Algorithmusfunktionsobjekt) |
(C++20) |
|
| dreht die Reihenfolge der Elemente in einem Bereich (Funktionstemplate & Algorithmusfunktionsobjekt) | |
(C++20) |
|
(C++23)(C++23) |
verschiebt Elemente in einem Bereich (Algorithmusfunktionsobjekt) |