Namespaces
Variants

std::ranges:: shift_left, std::ranges:: shift_right

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Permutation operations
Fold operations
Operations on uninitialized storage
Return types
Definiert im Header <algorithm>
Aufrufsignatur
template < std:: permutable I, std:: sentinel_for < I > S >

constexpr ranges:: subrange < I >

shift_left ( I first, S last, std:: iter_difference_t < I > n ) ;
(1) (seit C++23)
(2) (seit C++23)
template < std:: permutable I, std:: sentinel_for < I > S >

constexpr ranges:: subrange < I >

shift_right ( I first, S last, std:: iter_difference_t < I > n ) ;
(3) (seit C++23)
(4) (seit C++23)

Verschiebt die Elemente im Bereich [ first , last ) oder r um n Positionen. Das Verhalten ist undefiniert, wenn [ first , last ) kein gültiger Bereich ist.

1) Verschiebt die Elemente in Richtung des Anfangs des Bereichs:
  • Wenn n == 0 || n >= last - first , gibt es keine Effekte.
  • Wenn n < 0 , ist das Verhalten undefiniert.
  • Andernfalls wird für jede Ganzzahl i in [ 0 , last - first - n ) das Element, das ursprünglich an Position first + n + i stand, an Position first + i verschoben. Die Verschiebungen werden in aufsteigender Reihenfolge von i beginnend bei 0 durchgeführt.
3) Verschiebt die Elemente in Richtung des Endes des Bereichs:
  • Wenn n == 0 || n >= last - first , gibt es keine Effekte.
  • Wenn n < 0 , ist das Verhalten undefiniert.
  • Andernfalls wird für jede ganze Zahl i in [ 0 , last - first - n ) das Element, das ursprünglich an Position first + i stand, an Position first + n + i verschoben. Falls I das Konzept bidirectional_iterator modelliert, werden die Verschiebungen in absteigender Reihenfolge von i beginnend bei last - first - n - 1 durchgeführt.
2,4) Gleich wie (1) oder (3) entsprechend, verwendet jedoch r als Bereich, als ob ranges:: begin ( r ) als first und ranges:: end ( r ) als last verwendet würde.

Elemente, die sich im ursprünglichen Bereich befinden, aber nicht im neuen Bereich, verbleiben in einem gültigen, aber nicht spezifizierten Zustand.

Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithm Function Objects (informell bekannt als Niebloids ), das heißt:

Inhaltsverzeichnis

Parameter

first, last - das Iterator-Sentinel-Paar, das den Bereich der zu verschiebenden Elemente definiert
r - der Bereich der zu verschiebenden Elemente
n - die Anzahl der zu verschiebenden Positionen

Rückgabewert

1,2) { first, /*NEW_LAST*/ } , wobei NEW_LAST das Ende des resultierenden Bereichs ist und äquivalent zu:
  • first + ( last - first - n ) , falls n kleiner ist als last - first ;
  • first andernfalls.
3,4) { /*NEW_FIRST*/ , last } , wobei NEW_FIRST der Anfang des resultierenden Bereichs ist und äquivalent zu:
  • first + n , falls n kleiner als last - first ist;
  • last andernfalls.

Komplexität

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

Hinweise

ranges::shift_left / ranges::shift_right haben auf gängigen Implementierungen eine bessere Effizienz, wenn I das Konzept bidirectional_iterator oder (noch besser) random_access_iterator modelliert.

Implementierungen (z.B. MSVC STL ) können Vektorisierung ermöglichen, wenn der Iteratortyp contiguous_iterator modelliert und das Vertauschen seines Werttyps weder nicht-triviale spezielle Memberfunktionen noch ADL -gefundene swap -Funktionen aufruft.

Feature-Test-Makro Wert Std Feature
__cpp_lib_shift 202202L (C++23) std::ranges::shift_left und std::ranges::shift_right

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::ranges::shift_left(a, 3);
    std::ranges::shift_left(b, 3);
    std::ranges::shift_left(c, 3);
    std::cout << a << "  " << b << "  " << c << '\n';
    std::ranges::shift_right(a, 2);
    std::ranges::shift_right(b, 2);
    std::ranges::shift_right(c, 2);
    std::cout << a << "  " << b << "  " << c << '\n';
    std::ranges::shift_left(a, 8); // hat keine Wirkung: n >= last - first
    std::ranges::shift_left(b, 8); // ditto
    std::ranges::shift_left(c, 8); // ditto
    std::cout << a << "  " << b << "  " << c << '\n';
//  std::ranges::shift_left(a, -3); // UB
}

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

verschiebt eine Reihe von Elementen an einen neuen Speicherort
(Algorithmus-Funktionsobjekt)
verschiebt eine Reihe von Elementen in umgekehrter Reihenfolge an einen neuen Speicherort
(Algorithmus-Funktionsobjekt)
rotiert die Reihenfolge der Elemente in einem Bereich
(Algorithmus-Funktionsobjekt)
verschiebt Elemente in einem Bereich
(Funktions-Template)