Namespaces
Variants

std::shift_left, std::shift_right

cppreference.net에서
 
 
알고리즘 라이브러리
제약된 알고리즘 및 범위 기반 알고리즘 (C++20)
제약된 알고리즘, 예: ranges::copy, ranges::sort, ...
정렬 및 관련 연산
분할 연산
(C++11)    

정렬 연산
이진 탐색 연산
(분할된 범위에 대해)
집합 연산 (정렬된 범위에 대해)
병합 연산 (정렬된 범위에 대해)
힙 연산
최소/최대 연산
(C++11)
(C++17)
사전식 비교 연산
순열 연산


 
헤더 <algorithm>
template< class ForwardIt >
constexpr ForwardIt shift_left( ForwardIt first, ForwardIt last,
                                typename std::iterator_traits<ForwardIt>::
                                    difference_type n );
에 정의됨 (1) (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) (C++20부터)
template< class ForwardIt >
constexpr ForwardIt shift_right( ForwardIt first, ForwardIt last,
                                 typename std::iterator_traits<ForwardIt>::
                                     difference_type n );
(3) (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) (C++20부터)

범위 [first, last)의 요소를 n만큼 이동시킵니다.

1) 요소를 범위의 시작 쪽으로 이동시킵니다.
  • 만약 n == 0 || n >= last - first이면 아무 효과가 없습니다.
  • 그렇지 않으면, i의 각 정수 [0, last - first - n)에 대해, 원래 first + n + i에 있던 요소를 first + i로 이동시킵니다.
이동은 i의 증가 순서로 0부터 시작하여 수행됩니다.
3) 요소를 범위의 끝 쪽으로 이동시킵니다.
  • 만약 n == 0 || n >= last - first이면 아무 효과가 없습니다.
  • 그렇지 않으면, i의 각 정수 [0, last - first - n)에 대해, 원래 first + i에 있던 요소를 first + n + i로 이동시킵니다.
만약 ForwardIt이 LegacyBidirectionalIterator 요구 사항을 충족한다면, 이동은 i의 감소 순서로 last - first - n - 1부터 시작하여 수행됩니다.
2,4) 각각 (1) 및 (3)과 동일하지만, policy에 따라 실행되며 이동 순서는 임의일 수 있습니다.
이 오버로드는 std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>이 true인 경우에만 오버로드 해석에 참여합니다.

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

다음 조건 중 하나라도 만족하면 동작이 정의되지 않습니다:

매개변수

first, last - 이동할 요소들의 범위 를 정의하는 반복자 쌍
n - 이동할 위치의 수
policy - 사용할 실행 정책
타입 요구사항
-
ForwardIt 는 LegacyForwardIterator 의 요구사항을 충족해야 함

반환값

1,2) 결과 범위의 끝.
3,4) 결과 범위의 시작.
  • 만약 n 이 std:: distance ( first, last ) 보다 작으면, std:: next ( first, n ) 와 같은 반복자를 반환합니다.
  • 그렇지 않으면, last 를 반환합니다.

복잡도

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

예외

ExecutionPolicy 라는 템플릿 매개변수를 사용하는 오버로드는 다음과 같이 오류를 보고합니다:

  • 알고리즘의 일부로 호출된 함수 실행 중 예외가 발생하고 ExecutionPolicy 가 표준 정책 중 하나인 경우, std::terminate 가 호출됩니다. 다른 ExecutionPolicy 의 경우 동작은 구현에 따라 정의됩니다.
  • 알고리즘이 메모리 할당에 실패하는 경우, std::bad_alloc 이 throw됩니다.

참고 사항

기능 테스트 매크로 값 표준 기능
__cpp_lib_shift 201806L (C++20) std::shift_left 및 std::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::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); // 효과 없음: n >= last - first
    std::shift_left(begin(b), end(b), 8); // 동일
    std::shift_left(begin(c), end(c), 8); // 동일
    std::cout << a << "  " << b << "  " << c << '\n';
//  std::shift_left(begin(a), end(a), -3); // UB, e.g. segfault
}

가능한 출력:

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

함께 보기

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