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
헤더 파일에 정의됨 <algorithm>
함수 시그니처
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) (C++23부터)
(2) (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) (C++23부터)
(4) (C++23부터)

범위 [ first , last ) 또는 r 내의 요소들을 n 위치만큼 이동시킵니다. [ first , last ) 가 유효한 범위가 아닌 경우 동작은 정의되지 않습니다.

1) 범위의 시작 방향으로 요소들을 이동시킵니다:
  • 만약 n == 0 || n >= last - first 인 경우, 아무런 효과도 없습니다.
  • 만약 n < 0 인 경우, 동작은 정의되지 않습니다.
  • 그렇지 않으면, [ 0 , last - first - n ) 범위의 모든 정수 i 에 대해, 원래 first + n + i 위치에 있던 요소를 first + i 위치로 이동시킵니다. 이동은 0 에서 시작하여 i 의 증가 순서로 수행됩니다.
3) 범위의 끝 방향으로 요소들을 이동시킵니다:
  • 만약 n == 0 || n >= last - first 인 경우, 아무런 영향도 없습니다.
  • 만약 n < 0 인 경우, 동작은 정의되지 않습니다.
  • 그렇지 않으면, 모든 정수 i 에 대해 [ 0 , last - first - n ) 범위에서, 원래 위치 first + i 에 있던 요소를 위치 first + n + i 로 이동시킵니다. 만약 I bidirectional_iterator 를 모델링하면, 이동 작업은 i 의 감소 순서로 last - first - n - 1 에서 시작하여 수행됩니다.
2,4) (1) 또는 (3) 과 동일하지만, r 를 범위로 사용하며, 마치 ranges:: begin ( r ) first 로, ranges:: end ( r ) last 로 사용하는 것과 같습니다.

원본 범위에 있지만 새로운 범위에는 없는 요소들은 유효하지만 지정되지 않은 상태로 남습니다.

이 페이지에서 설명하는 함수형 개체들은 algorithm function objects (일반적으로 niebloids 로 알려진)입니다. 즉:

목차

매개변수

first, last - 이동할 요소들의 범위 를 정의하는 반복자-감시자 쌍
r - 이동할 요소들의 범위
n - 이동할 위치의 수

반환값

1,2) { first, /*NEW_LAST*/ } , 여기서 NEW_LAST 는 결과 범위의 끝이며 다음과 동일합니다:
  • first + ( last - first - n ) , 만약 n last - first 보다 작은 경우;
  • first 그렇지 않은 경우.
3,4) { /*NEW_FIRST*/ , last } , 여기서 NEW_FIRST 는 결과 범위의 시작 부분이며 다음 값과 동일합니다:
  • first + n , 만약 n last - first 보다 작은 경우;
  • last 그 외의 경우.

복잡도

1,2) 최대 ranges:: distance ( first, last ) - n 번의 할당.
3,4) 최대 ranges:: distance ( first, last ) - n 번의 할당 또는 교환.

참고 사항

ranges::shift_left / ranges::shift_right I bidirectional_iterator 또는 (더 나은 경우) random_access_iterator 를 모델링할 경우 일반적인 구현에서 더 나은 효율성을 가집니다.

구현체들(예: MSVC STL )은 반복자 타입이 contiguous_iterator 를 모델링하고 해당 값 타입의 교환이 비트리비얼 특수 멤버 함수나 ADL 에서 발견된 swap 을 호출하지 않을 때 벡터화를 활성화할 수 있습니다.

기능 테스트 매크로 표준 기능
__cpp_lib_shift 202202L (C++23) std::ranges::shift_left std::ranges::shift_right

예제

#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); // 효과 없음: n >= last - first
    std::ranges::shift_left(b, 8); // 동일
    std::ranges::shift_left(c, 8); // 동일
    std::cout << a << "  " << b << "  " << c << '\n';
//  std::ranges::shift_left(a, -3); // UB
}

가능한 출력:

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   . . δ ε ζ η .

참고 항목

요소 범위를 새로운 위치로 이동
(알고리즘 함수 객체)
요소 범위를 역순으로 새로운 위치로 이동
(알고리즘 함수 객체)
범위 내 요소들의 순서를 회전
(알고리즘 함수 객체)
범위 내 요소들을 이동
(함수 템플릿)