std::shift_left, std::shift_right
cppreference.net에서
|
헤더 <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인 경우에만 오버로드 해석에 참여합니다.원래 범위에 있었지만 새 범위에 없는 요소는 유효하지만 지정되지 않은 상태로 남습니다.
다음 조건 중 하나라도 만족하면 동작이 정의되지 않습니다:
n >= 0가true가 아닙니다.-
*first의 유형이 MoveAssignable이 아닙니다. -
shift_right의 경우,ForwardIt이 LegacyBidirectionalIterator도 아니고 ValueSwappable도 아닙니다.
매개변수
| first, last | - | 이동할 요소들의 범위 를 정의하는 반복자 쌍 |
| n | - | 이동할 위치의 수 |
| policy | - | 사용할 실행 정책 |
| 타입 요구사항 | ||
-
ForwardIt
는
LegacyForwardIterator
의 요구사항을 충족해야 함
|
||
반환값
1,2)
결과 범위의 끝.
- 만약 n 이 std:: distance ( first, last ) 보다 작으면, std:: next ( first, ( std:: distance ( first, last ) - n ) ) 와 같은 반복자를 반환합니다.
- 그렇지 않으면, first 를 반환합니다.
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) |
요소 범위를 새 위치로 이동 (함수 템플릿 & 알고리즘 함수 객체) |
(C++20) |
|
(C++11) |
요소 범위를 역순으로 새 위치로 이동 (함수 템플릿 & 알고리즘 함수 객체) |
(C++20) |
|
| 범위 내 요소들의 순서를 회전 (함수 템플릿 & 알고리즘 함수 객체) | |
(C++20) |
|
(C++23)(C++23) |
요소들을 범위 내에서 이동 (알고리즘 함수 객체) |