Iterator library
반복자는 C++ 프로그램이 다양한 데이터 구조(예를 들어, 포인터 의 일반화로, 컨테이너 와 범위 (C++20부터) )를 일관된 방식으로 작업할 수 있도록 합니다. 반복자 라이브러리는 반복자, 반복자 특성, 어댑터 및 유틸리티 함수에 대한 정의를 제공합니다.
반복자는 포인터의 추상화이므로, 그 의미론은 C++에서 포인터 의미론의 대부분을 일반화한 것입니다. 이는 모든 function template 이 반복자를 받는 경우 일반 포인터와도 동일하게 작동하도록 보장합니다.
반복자 범주
다음과 같은 다섯 가지 (C++17까지) 여섯 가지 (C++17부터) 종류의 반복자가 있습니다: LegacyInputIterator , LegacyOutputIterator , LegacyForwardIterator , LegacyBidirectionalIterator , LegacyRandomAccessIterator , 그리고 LegacyContiguousIterator (C++17부터) . (가장 기본적인 반복자 유형에 대해서는 LegacyIterator 도 참조하십시오.)
반복자의 각 범주는 특정 타입으로 정의되기보다는, 해당 반복자에서 수행 가능한 연산들로 정의됩니다. 이러한 정의 방식은 필요한 연산들을 지원하는 모든 타입이 반복자로 사용될 수 있음을 의미합니다 -- 예를 들어, 포인터는 LegacyRandomAccessIterator 에 필요한 모든 연산을 지원하므로, LegacyRandomAccessIterator 가 요구되는 모든 곳에서 포인터를 사용할 수 있습니다.
모든 반복자 카테고리( LegacyOutputIterator 제외)는 계층 구조로 조직화될 수 있으며, 더 강력한 반복자 카테고리(예: LegacyRandomAccessIterator )는 덜 강력한 카테고리(예: LegacyInputIterator )의 연산들을 지원합니다. 만약 반복자가 이러한 카테고리 중 하나에 속하면서 LegacyOutputIterator 의 요구사항도 만족한다면, 이를 mutable 반복자라고 부르며 both 입력과 출력을 모두 지원합니다. Non-mutable 반복자는 constant 반복자라고 불립니다.
|
반복자가 제공하는 모든 연산이 반복자 카테고리 요구사항을 충족하는 constexpr 함수 일 경우, 해당 반복자를 constexpr 반복자라고 합니다. |
(since C++20) |
| 반복자 카테고리 | 연산 및 저장소 요구사항 | ||||||
|---|---|---|---|---|---|---|---|
| 쓰기 | 읽기 | 증가 | 감소 |
임의
접근 |
연속
저장소 |
||
|
다중 패스
없이 |
다중 패스
포함 |
||||||
| LegacyIterator | 필수 | ||||||
| LegacyOutputIterator | 필수 | 필수 | |||||
|
LegacyInputIterator
(쓰기 연산을 지원하는 경우 가변) |
필수 | 필수 | |||||
|
LegacyForwardIterator
( LegacyInputIterator 도 만족) |
필수 | 필수 | 필수 | ||||
|
LegacyBidirectionalIterator
( LegacyForwardIterator 도 만족) |
필수 | 필수 | 필수 | 필수 | |||
|
LegacyRandomAccessIterator
( LegacyBidirectionalIterator 도 만족) |
필수 | 필수 | 필수 | 필수 | 필수 | ||
|
LegacyContiguousIterator
[1]
( LegacyRandomAccessIterator 도 만족) |
필수 | 필수 | 필수 | 필수 | 필수 | 필수 | |
- ↑ LegacyContiguousIterator 카테고리는 공식적으로 C++17에서만 명시되었으나, std::vector , std::basic_string , std::array , 그리고 std::valarray 의 반복자들, 그리고 C 배열에 대한 포인터들은 C++17 이전 코드에서 종종 별도의 카테고리로 취급되었습니다.
참고: 위 표의 한 행에 필요한 연산들을 지원하는 타입이 반드시 해당 카테고리에 속하는 것은 아닙니다. 전체 요구사항 목록은 카테고리 페이지를 참조하십시오.
정의
타입과 쓰기 가능성
입력 반복자
i
는 표현식
*
i
를 지원하며, 이는 특정
객체 타입
T
의 값을 결과로 가집니다. 이를 반복자의
값 타입
이라고 합니다.
출력 반복자
i
는 해당 반복자에
쓰기 가능한
(C++20까지)
indirectly_writable
(C++20 이후)
비어 있지 않은 타입 집합을 가집니다; 각각의 이러한 타입
T
에 대해, 표현식
*
i
=
o
가 유효하며, 여기서
o
는 타입
T
의 값입니다.
동등성이 정의된 모든 반복자 타입
X
에 대해
(C++20 이전)
, 해당 반복자의
difference type
이라고 불리는 대응되는 부호 있는
정수
(C++20 이전)
정수형
(C++20 이후)
타입이 존재합니다.
역참조 가능성과 유효성
일반적인 배열 포인터가 배열의 마지막 요소를 지난 위치를 가리키는 포인터 값을 보장하는 것처럼, 모든 반복자 유형에 대해 해당 시퀀스의 마지막 요소를 지난 위치를 가리키는 반복자 값이 존재합니다. 이러한 값을 past-the-end 값이라고 부릅니다.
반복자 i 의 값들 중에서 표현식 * i 가 정의되는 값들을 역참조 가능(dereferenceable) 하다고 합니다. 표준 라이브러리 는 past-the-end 값들이 역참조 가능하다고 가정하지 않습니다.
반복자는 또한 어떤 시퀀스와도 연관되지 않은 singular 값을 가질 수 있습니다. 대부분의 표현식에 대한 결과는 singular 값에 대해 정의되지 않습니다; 유일한 예외는
- 단일 값을 보유하는 반복자에 비단일 값을 할당하는 경우,
- 단일 값을 보유하는 반복자를 파괴하는 경우, 그리고
- DefaultConstructible 요구 사항을 충족하는 반복자의 경우, 값 초기화 된 반복자를 복사 또는 이동 (C++11부터) 연산의 소스로 사용하는 경우.
이러한 경우 단일 값은 다른 값과 동일한 방식으로 덮어쓰여집니다. 역참조 가능한 값은 항상 비단일(non-singular)입니다.
유효하지 않은 반복자는 특이 상태(singular)일 수 있는 반복자입니다.
범위
표준 라이브러리의 데이터 구조를 조작하는 알고리즘 템플릿 대부분은 범위를 사용하는 인터페이스를 갖습니다.
|
반복자 j 가 반복자 i 로부터 도달 가능(reachable) 하다는 것은 ++ i 표현식을 유한 번 적용하여 i == j 를 만들 수 있을 때만 성립합니다. j 가 i 로부터 도달 가능하다면, 이들은 동일한 시퀀스의 요소들을 참조합니다.
범위(range)
는 계산의 시작과 끝을 지정하는 한 쌍의 반복자입니다.
|
(until C++20) |
|
범위 는 다음 중 하나로 표기할 수 있습니다:
반복자-센티넬 범위
범위를 나타내는 반복자와 센티넬은 비교 가능합니다.
센티넬 s 가 반복자 i 로부터 도달 가능 하다는 것은 ++ i 표현식을 유한한 횟수 적용하여 i == s 를 만들 수 있을 때만 성립합니다.
만약
s
가
i
로부터 도달 가능하다면,
개수 지정 범위
개수 지정 범위
i
개수 지정 범위
i
|
(C++20부터) |
표준 라이브러리 함수를 유효하지 않은 범위에 적용한 결과는 정의되지 않습니다.
반복자 개념 (since C++20)
C++17 반복자와는 다른 concepts 에 기반한 새로운 반복자 체계입니다. 기본 분류 체계는 유사하게 유지되지만, 개별 반복자 카테고리에 대한 요구 사항은 다소 다릅니다.
|
정의된 네임스페이스
std
|
|
|
(C++20)
|
*
연산자를 적용하여 간접적으로 읽을 수 있는 타입을 명시
(concept) |
|
(C++20)
|
반복자의 참조 객체에 값을 쓸 수 있음을 명시
(concept) |
|
(C++20)
|
semiregular
타입이 전위 및 후위 증가 연산자로 증가될 수 있음을 명시
(concept) |
|
(C++20)
|
weakly_incrementable
타입에 대한 증가 연산이
equality-preserving
이며 타입이
equality_comparable
임을 명시
(concept) |
|
(C++20)
(C++20)
|
타입이 (부호 있는) 정수형처럼 동작함을 명시
( 설명 전용 개념* ) |
|
(C++20)
|
타입의 객체가 증가 및 역참조될 수 있음을 명시
(concept) |
|
(C++20)
|
타입이
input_or_output_iterator
타입에 대한 sentinel임을 명시
(concept) |
|
(C++20)
|
-
연산자가 반복자와 sentinel에 적용되어 상수 시간에 차이를 계산할 수 있음을 명시
(concept) |
|
(C++20)
|
타입이 입력 반복자임을 명시, 즉 참조 값이 읽히고 전위 및 후위 증가될 수 있음
(concept) |
|
(C++20)
|
타입이 주어진 값 타입에 대한 출력 반복자임을 명시, 즉 해당 타입의 값이 쓰여질 수 있고 전위 및 후위 증가될 수 있음
(concept) |
|
(C++20)
|
input_iterator
가 전방 반복자임을 명시, 동등 비교와 다중 패스를 지원
(concept) |
|
(C++20)
|
forward_iterator
가 양방향 반복자임을 명시, 역방향 이동을 지원
(concept) |
|
(C++20)
|
bidirectional_iterator
가 임의 접근 반복자임을 명시, 상수 시간 이동과 첨자 연산을 지원
(concept) |
|
(C++20)
|
random_access_iterator
가 연속 반복자임을 명시, 메모리에서 연속적인 요소를 참조
(concept) |
반복자 관련 타입 (C++20부터)
|
정의된 네임스페이스
std
|
|
|
(C++20)
|
weakly_incrementable
타입의 차이 타입을 계산함
(클래스 템플릿) |
|
(C++20)
|
indirectly_readable
타입의 값 타입을 계산함
(클래스 템플릿) |
|
(C++20)
(C++20)
(C++23)
(C++20)
(C++20)
(C++20)
|
반복자의 연관 타입들을 계산함
(앨리어스 템플릿) |
반복자 기본 요소
|
반복자의 속성에 대한 통일된 인터페이스를 제공함
(클래스 템플릿) |
|
|
반복자 카테고리를 나타내는 데 사용되는 빈 클래스 타입들
(클래스) |
|
|
(C++17에서 사용 중단됨)
|
단순 반복자에 필요한 타입 정의를 용이하게 하는 기본 클래스
(클래스 템플릿) |
반복자 커스터마이제이션 포인트 (since C++20)
|
정의된 네임스페이스
std::ranges
|
|
|
(C++20)
|
객체를 역참조한 결과를 해당 rvalue 참조 타입으로 캐스팅합니다
(customization point object) |
|
(C++20)
|
두 개의 역참조 가능한 객체가 참조하는 값을 교환합니다
(customization point object) |
알고리즘 개념과 유틸리티 (since C++20)
일반적인 알고리즘 연산을 제약하기 쉽게 설계된 개념들과 관련 유틸리티 템플릿 세트.
|
헤더 파일에 정의됨
<iterator>
|
|
|
정의된 네임스페이스
std
|
|
간접 호출 가능 개념 |
|
|
(C++20)
(C++20)
|
호출 가능 타입이
indirectly_readable
타입을 역참조한 결과로 호출될 수 있음을 명시
(concept) |
|
(C++20)
|
호출 가능 타입이
indirectly_readable
타입을 역참조한 결과로 호출될 때
predicate
를 만족함을 명시합니다
(concept) |
|
(C++20)
|
호출 가능 타입이 두 개의
indirectly_readable
타입을 역참조한 결과로 호출될 때
predicate
를 만족함을 명시합니다.
(concept) |
|
(C++20)
|
호출 가능 타입이 두 개의
indirectly_readable
타입을 역참조한 결과로 호출될 때
equivalence_relation
을 만족함을 명시함
(concept) |
|
(C++20)
|
호출 가능 타입이 두 개의
indirectly_readable
타입을 역참조한 결과로 호출될 때
strict_weak_order
를 만족함을 명시합니다.
(concept) |
공통 알고리즘 요구사항 |
|
|
(C++20)
|
값들이
indirectly_readable
타입으로부터
indirectly_writable
타입으로 이동될 수 있음을 명시함
(concept) |
|
(C++20)
|
indirectly_readable
타입에서
indirectly_writable
타입으로 값들이 이동될 수 있으며, 해당 이동이 중간 객체를 통해 수행될 수 있음을 명시합니다
(concept) |
|
(C++20)
|
indirectly_readable
타입에서
indirectly_writable
타입으로 값이 복사될 수 있음을 명시
(concept) |
|
(C++20)
|
indirectly_readable
타입에서
indirectly_writable
타입으로 값들이 복사될 수 있으며, 복사가 중간 객체를 통해 수행될 수 있음을 명시합니다
(concept) |
|
(C++20)
|
두 개의
indirectly_readable
타입이 참조하는 값들이 교환될 수 있음을 명시
(concept) |
|
(C++20)
|
두 개의
indirectly_readable
타입이 참조하는 값들을 비교할 수 있음을 명시
(concept) |
|
(C++20)
|
제자리에서 요소들을 재배열하는 알고리즘들의 공통 요구사항을 명시합니다
(concept) |
|
(C++20)
|
정렬된 시퀀스를 요소 복사를 통해 출력 시퀀스로 병합하는 알고리즘의 요구 사항을 명시함
(concept) |
|
(C++20)
|
시퀀스를 정렬된 시퀀스로 재배열하는 알고리즘의 공통 요구사항을 명시함
(concept) |
유틸리티 |
|
|
(C++20)
|
일부
indirectly_readable
타입들을 역참조한 결과에 대해 호출 가능 객체를 호출한 결과를 계산함
(alias template) |
|
(C++20)
|
투영(projection)을 받는 알고리즘의 제약 조건을 지정하기 위한 헬퍼 템플릿
(alias template) |
|
(C++26)
|
투영을 통해
indirectly_readable
타입의 값 타입을 계산함
(alias template) |
반복자 어댑터
|
역순 순회를 위한 반복자 어댑터
(클래스 템플릿) |
|
|
(C++14)
|
인수로부터 타입이 추론되는
std::reverse_iterator
를 생성합니다
(함수 템플릿) |
|
컨테이너의 끝에 삽입하기 위한 반복자 어댑터
(클래스 템플릿) |
|
|
인수로부터 추론된 타입의
std::back_insert_iterator
를 생성합니다
(함수 템플릿) |
|
|
컨테이너의 앞쪽에 삽입을 위한 iterator 어댑터
(클래스 템플릿) |
|
|
인수로부터 추론된 타입의
std::front_insert_iterator
를 생성합니다
(함수 템플릿) |
|
|
컨테이너에 삽입하기 위한 iterator 어댑터
(클래스 템플릿) |
|
|
인수에서 유추된 타입의
std::insert_iterator
를 생성합니다
(함수 템플릿) |
|
|
(C++23)
|
반복자를 상수 반복자로 변환하는 반복자 어댑터
(클래스 템플릿) |
|
(C++23)
|
주어진 타입에 대한 상수 반복자 타입을 계산함
(alias template) |
|
(C++23)
|
상수 반복자와 함께 사용할 sentinel 타입을 계산합니다
(alias template) |
|
(C++23)
|
인자로부터 타입이 추론되는
std::const_iterator
를 생성합니다
(함수 템플릿) |
|
(C++23)
|
인자의 타입에서 추론된
std::const_sentinel
을 생성합니다
(함수 템플릿) |
|
(C++11)
|
rvalue로 역참조하는 반복자 어댑터
(클래스 템플릿) |
|
(C++20)
|
std::move_iterator
를 위한 센티넬 어댑터
(클래스 템플릿) |
|
(C++11)
|
인수로부터 타입이 추론된
std::move_iterator
를 생성합니다
(함수 템플릿) |
|
(C++20)
|
반복자 타입과 센티널을 공통 반복자 타입으로 적응시킵니다
(클래스 템플릿) |
|
(C++20)
|
자신의 범위 경계를 알고 있는 반복자와 함께 사용하기 위한 기본 센티널
(클래스) |
|
(C++20)
|
범위의 끝까지 거리를 추적하는 반복자 어댑터
(클래스 템플릿) |
|
(C++20)
|
어떤
weakly_incrementable
타입과도 항상 같지 않음을 비교하는 sentinel
(클래스) |
스트림 반복자
|
std::basic_istream
에서 읽어들이는 입력 반복자
(클래스 템플릿) |
|
|
std::basic_ostream
에 쓰는 출력 반복자
(클래스 템플릿) |
|
|
std::basic_streambuf
에서 읽어들이는 입력 반복자
(클래스 템플릿) |
|
|
std::basic_streambuf
에 쓰는 출력 반복자
(클래스 템플릿) |
반복자 연산
|
헤더에 정의됨
<iterator>
|
|
|
반복자를 주어진 거리만큼 전진
(함수 템플릿) |
|
|
두 반복자 사이의 거리를 반환
(함수 템플릿) |
|
|
(C++11)
|
반복자를 증가
(함수 템플릿) |
|
(C++11)
|
반복자를 감소
(함수 템플릿) |
|
(C++20)
|
반복자를 주어진 거리만큼 또는 주어진 경계까지 전진
(알고리즘 함수 객체) |
|
(C++20)
|
반복자와 센티넬 사이, 또는 범위의 시작과 끝 사이의 거리를 반환
(알고리즘 함수 객체) |
|
(C++20)
|
반복자를 주어진 거리만큼 또는 경계까지 증가
(알고리즘 함수 객체) |
|
(C++20)
|
반복자를 주어진 거리만큼 또는 경계까지 감소
(알고리즘 함수 객체) |
범위 접근 (since C++11)
이 비멤버 함수 템플릿들은 컨테이너, 일반 배열, 그리고 std::initializer_list 를 위한 일반적인 인터페이스를 제공합니다.
|
헤더 파일에 정의됨
<array>
|
|
|
헤더 파일에 정의됨
<deque>
|
|
|
헤더 파일에 정의됨
<flat_map>
|
|
|
헤더 파일에 정의됨
<flat_set>
|
|
|
헤더 파일에 정의됨
<forward_list>
|
|
|
헤더 파일에 정의됨
<inplace_vector>
|
|
|
헤더 파일에 정의됨
<iterator>
|
|
|
헤더 파일에 정의됨
<list>
|
|
|
헤더 파일에 정의됨
<map>
|
|
|
헤더 파일에 정의됨
<regex>
|
|
|
헤더 파일에 정의됨
<set>
|
|
|
헤더 파일에 정의됨
<span>
|
|
|
헤더 파일에 정의됨
<string>
|
|
|
헤더 파일에 정의됨
<string_view>
|
|
|
헤더 파일에 정의됨
<unordered_map>
|
|
|
헤더 파일에 정의됨
<unordered_set>
|
|
|
헤더 파일에 정의됨
<vector>
|
|
|
네임스페이스에 정의됨
std
|
|
|
(C++11)
(C++14)
|
컨테이너나 배열의 시작 부분을 가리키는 반복자를 반환합니다
(함수 템플릿) |
|
(C++11)
(C++14)
|
컨테이너나 배열의 끝을 가리키는 반복자를 반환합니다
(함수 템플릿) |
|
(C++14)
|
컨테이너나 배열의 시작 부분을 가리키는 역방향 반복자를 반환합니다
(함수 템플릿) |
|
(C++14)
|
컨테이너나 배열의 끝을 가리키는 역방향 반복자를 반환합니다
(함수 템플릿) |
|
(C++17)
(C++20)
|
컨테이너나 배열의 크기를 반환합니다
(함수 템플릿) |
|
(C++17)
|
컨테이너가 비어 있는지 확인합니다
(함수 템플릿) |
|
(C++17)
|
기반 배열에 대한 포인터를 얻습니다
(함수 템플릿) |
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| CWG 1181 | C++98 | 배열 타입은 값 타입이 될 수 없었음 | 가능함 |
| LWG 208 | C++98 | past-the-end 반복자는 항상 non-singular였음 | singular일 수 있음 |
| LWG 278 | C++98 | 반복자의 유효성이 정의되지 않았음 | 항상 non-singular로 정의됨 |
| LWG 324 | C++98 | 출력 반복자가 값 타입을 가짐 | 출력 반복자는 대신 쓰기 가능 타입을 가짐 |
| LWG 407 | C++98 | singular 반복자는 소멸될 수 없었음 | 허용됨 |
|
LWG 408
( N3066 ) |
C++98 | singular 반복자는 복사될 수 없었음 | 값 초기화된 경우 허용됨 |
|
LWG 1185
( N3066 ) |
C++98 |
LegacyForwardIterator
,
LegacyBidirectionalIterator
및 LegacyRandomAccessIterator 는 항상 LegacyOutputIterator 를 만족함 |
LegacyOutputIterator 를 만족하지 않을 수 있음 |
|
LWG 1210
( N3066 ) |
C++98 |
반복자 singularity와 도달 가능성의 정의가
컨테이너에 의존했음 |
시퀀스에 의존하도록 변경 |
| LWG 3009 | C++17 |
<string_view>
가 범위 접근 함수 템플릿을
제공하지 않았음 |
이러한 템플릿을 제공함 |
| LWG 3987 | C++23 |
<flat_map>
와
<flat_set>
가
범위 접근 함수 템플릿을 제공하지 않았음 |
이러한 템플릿을 제공함 |