std:: input_iterator_tag, std:: output_iterator_tag, std:: forward_iterator_tag, std:: bidirectional_iterator_tag, std:: random_access_iterator_tag, std:: contiguous_iterator_tag
|
헤더 파일에 정의됨
<iterator>
|
||
|
struct
input_iterator_tag
{
}
;
|
(1) | |
|
struct
output_iterator_tag
{
}
;
|
(2) | |
|
struct
forward_iterator_tag
:
public
input_iterator_tag
{
}
;
|
(3) | |
|
struct
bidirectional_iterator_tag
:
public
forward_iterator_tag
{
}
;
|
(4) | |
|
struct
random_access_iterator_tag
:
public
bidirectional_iterator_tag
{
}
;
|
(5) | |
|
struct
contiguous_iterator_tag
:
public
random_access_iterator_tag
{
}
;
|
(6) | (C++20부터) |
반복자의 카테고리를 정의합니다. 각 태그는 빈 타입입니다.
목차 |
반복자 카테고리
모든
LegacyIterator
타입
It
에 대해,
typedef
std::
iterator_traits
<
It
>
::
iterator_category
는 이 태그 타입들 중 하나의 별칭으로 정의되어야 하며,
It
가 속한 가장 구체적인 카테고리를 나타내야 합니다.
-
input_iterator_tag는 LegacyInputIterator 에 대응됩니다. -
output_iterator_tag는 LegacyOutputIterator 에 대응됩니다. -
forward_iterator_tag는 LegacyForwardIterator 에 대응됩니다. -
bidirectional_iterator_tag는 LegacyBidirectionalIterator 에 대응됩니다. -
random_access_iterator_tag는 LegacyRandomAccessIterator 에 대응됩니다.
반복자 카테고리 태그는 카테고리가 의미하는 특정 요구 사항 집합에 대해 가장 효율적인 알고리즘을 선택하는 데 사용할 수 있는 정보를 담고 있습니다.
Iterator 개념
모든
만약
어떤 경우든, 각 개념은 필요한 연산들이 지원되지 않으면 태그와 관계없이 만족되지 않습니다. |
(C++20부터) |
참고 사항
LegacyContiguousIterator
를 위한 별도의 태그는 존재하지 않습니다. 즉,
iterator_category
를 기반으로
LegacyContiguousIterator
를 판별하는 것은 불가능합니다.
연속 반복자를 위한 특수화된 알고리즘을 정의하려면
contiguous_iterator
개념을 사용하십시오.
(C++20부터)
output_iterator_tag
와
output_iterator
개념 사이에는 대응 관계가 존재하지 않습니다.
iterator_concept
을
output_iterator_tag
로 설정하는 것은 해당 타입이
input_iterator
를 모델링하지 않음을 나타낼 뿐입니다.
예제
이터레이터 카테고리 태그를 기반으로 알고리즘을 선택하는 일반적인 기법은 디스패처 함수를 사용하는 것입니다(대안으로 std::enable_if 가 있습니다). 이터레이터 태그 클래스들은 해당 개념 정의에서도 사용되어 사용 패턴만으로는 표현할 수 없는 요구사항을 나타냅니다. (C++20부터)
#include <iostream> #include <iterator> #include <list> #include <vector> // Using concepts (tag checking is part of the concepts themselves) template<std::bidirectional_iterator BDIter> void alg(BDIter, BDIter) { std::cout << "1. alg() \t called for bidirectional iterator\n"; } template<std::random_access_iterator RAIter> void alg(RAIter, RAIter) { std::cout << "2. alg() \t called for random-access iterator\n"; } // Legacy, using tag dispatch namespace legacy { // Quite often implementation details are hidden in a dedicated namespace namespace implementation_details { template<class BDIter> void alg(BDIter, BDIter, std::bidirectional_iterator_tag) { std::cout << "3. legacy::alg() called for bidirectional iterator\n"; } template<class RAIter> void alg(RAIter, RAIter, std::random_access_iterator_tag) { std::cout << "4. legacy::alg() called for random-access iterator\n"; } } // namespace implementation_details template<class Iter> void alg(Iter first, Iter last) { implementation_details::alg(first, last, typename std::iterator_traits<Iter>::iterator_category()); } } // namespace legacy int main() { std::list<int> l; alg(l.begin(), l.end()); // 1. legacy::alg(l.begin(), l.end()); // 3. std::vector<int> v; alg(v.begin(), v.end()); // 2. legacy::alg(v.begin(), v.end()); // 4. // std::istreambuf_iterator<char> i1(std::cin), i2; // alg(i1, i2); // compile error: no matching function for call // legacy::alg(i1, i2); // compile error: no matching function for call }
출력:
1. alg() called for bidirectional iterator 3. legacy::alg() called for bidirectional iterator 2. alg() called for random-access iterator 4. legacy::alg() called for random-access iterator
참고 항목
|
(C++17에서 사용 중단됨)
|
단순 반복자에 필요한 타입 정의를 용이하게 하는 기본 클래스
(클래스 템플릿) |
|
반복자의 속성에 대한 통일된 인터페이스를 제공함
(클래스 템플릿) |