Namensräume
Varianten
Aktionen

std::shift_left, std::shift_right

Von cppreference.com
< cpp‎ | algorithm
 
 
Algorithmenbibliothek
Beschränkte Algorithmen und Algorithmen für Bereiche (C++20)
Beschränkte Algorithmen, z.B. ranges::copy, ranges::sort, ...
Ausführungsrichtlinien (C++17)
Nicht-modifizierende Sequenzoperationen
Stapeloperationen
(C++17)
Suchoperationen
(C++11)                (C++11)(C++11)

Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Generierungsoperationen
Entfernungsoperationen
Ordnungsändernde Operationen
(bis C++17)(C++11)
shift_leftshift_right
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Zusammenführungsoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikographische Vergleichsoperationen
Permutationsoperationen
C-Bibliothek
Numerische Operationen
Operationen auf uninitialisiertem Speicher
 
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 [firstlast) um n Positionen.

1) Verschiebt die Elemente in Richtung des Anfangs des Bereichs.
  • Wenn n == 0 || n >= last - first, gibt es keine Effekte.
  • Andernfalls wird für jede ganze Zahl i in [0last - first - n) das Element, das sich ursprünglich an Position first + n + i befand, an Position first + i verschoben.
Die Verschiebungen werden in aufsteigender Reihenfolge von i ab 0 durchgeführt.
3) Verschiebt die Elemente in Richtung des Endes des Bereichs.
  • Wenn n == 0 || n >= last - first, gibt es keine Effekte.
  • Andernfalls wird für jede ganze Zahl i in [0last - first - n) das Element, das sich ursprünglich an Position first + i befand, an Position first + n + i verschoben.
Wenn ForwardIt die LegacyBidirectionalIterator-Anforderungen erfüllt, werden die Verschiebungen in absteigender Reihenfolge von i ab last - first - n - 1 durchgeführt.
2,4) Dasselbe wie (1) bzw. (3), aber 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>> true ist.

Elemente, die im ursprünglichen Bereich, aber nicht im neuen Bereich vorhanden sind, werden in einem gültigen, aber nicht spezifizierten Zustand belassen.

Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert

Inhalt

[edit] Parameter

first, last - das Iteratorenpaar, das den Bereich der zu verschiebenden Elemente definiert
n - die Anzahl der zu verschiebenden Positionen
policy - die Ausführungsrichtlinie, die verwendet werden soll
Typanforderungen
-
ForwardIt muss die Anforderungen von LegacyForwardIterator erfüllen.

[edit] Rückgabewert

1,2) Das Ende des resultierenden Bereichs.
  • Wenn 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 zurückgegeben, der gleich std::next(first, n) ist.
  • Andernfalls wird last zurückgegeben.

[edit] Komplexität

1,2) Höchstens std::distance(first, last) - n Zuweisungen.
3,4) Höchstens std::distance(first, last) - n Zuweisungen oder Swaps.

[edit] Ausnahmen

Die Überladungen mit einem Template-Parameter namens ExecutionPolicy berichten Fehler wie folgt

  • Wenn die Ausführung einer Funktion, die als Teil des Algorithmus aufgerufen wird, eine Ausnahme auslöst und ExecutionPolicy eine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist das Verhalten implementierungsabhängig.
  • Wenn dem Algorithmus der Speicher zur Neuzuweisung fehlt, wird std::bad_alloc ausgelöst.

[edit] Anmerkungen

Feature-Test-Makro Wert Std Feature
__cpp_lib_shift 201806L (C++20) std::shift_left und std::shift_right

[edit] Beispiel

#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); // has no effect: 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, e.g. 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   . . δ ε ζ η .

[edit] Siehe auch

(C++11)
Verschiebt einen Elementbereich an einen neuen Speicherort
(Funktionstempelat) [edit]
Verschiebt einen Elementbereich in umgekehrter Reihenfolge an einen neuen Speicherort
(Funktionstempelat) [edit]
Rotiert die Reihenfolge der Elemente in einem Bereich
(Funktionstemplate) [edit]
Verschiebt Elemente in einem Bereich
(Algorithmus-Funktionsobjekt)[edit]