Namespaces
Variants

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

From cppreference.net
Iterator library
Iterator concepts
Iterator primitives
input_iterator_tag output_iterator_tag forward_iterator_tag bidirectional_iterator_tag random_access_iterator_tag contiguous_iterator_tag
(C++20)
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Range access
(C++11) (C++14)
(C++14) (C++14)
(C++11) (C++14)
(C++14) (C++14)
(C++17) (C++20)
(C++17)
(C++17)
헤더 파일에 정의됨 <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 가 속한 가장 구체적인 카테고리를 나타내야 합니다.

  1. input_iterator_tag LegacyInputIterator 에 대응됩니다.
  2. output_iterator_tag LegacyOutputIterator 에 대응됩니다.
  3. forward_iterator_tag LegacyForwardIterator 에 대응됩니다.
  4. bidirectional_iterator_tag LegacyBidirectionalIterator 에 대응됩니다.
  5. random_access_iterator_tag LegacyRandomAccessIterator 에 대응됩니다.

반복자 카테고리 태그는 카테고리가 의미하는 특정 요구 사항 집합에 대해 가장 효율적인 알고리즘을 선택하는 데 사용할 수 있는 정보를 담고 있습니다.

Iterator 개념

모든 input_iterator 타입 It 에 대해, It :: iterator_concept (만약 std:: iterator_traits < It > 이 기본 템플릿으로부터 생성된 경우) 또는 std:: iterator_traits < It > :: iterator_concept (만약 std:: iterator_traits < It > 이 특수화된 경우)는 다음 태그들 중 하나에 대한 별칭으로 선언될 수 있으며, 이는 It 이 모델링하려는 가장 강력한 반복자 개념을 나타냅니다.

  1. input_iterator_tag input_iterator 에 대응합니다.
  2. forward_iterator_tag forward_iterator 에 대응합니다.
  3. bidirectional_iterator_tag bidirectional_iterator 에 대응합니다.
  4. random_access_iterator_tag random_access_iterator 에 대응합니다.
  5. contiguous_iterator_tag contiguous_iterator 에 대응합니다.

만약 iterator_concept 이 제공되지 않으면, iterator_category 이 대체로 사용됩니다. 만약 iterator_category 도 제공되지 않으면 (즉, It LegacyIterator 가 아니며), 그리고 std:: iterator_traits < It > 이 특수화되지 않은 경우, random_access_iterator_tag 이 가정됩니다.

어떤 경우든, 각 개념은 필요한 연산들이 지원되지 않으면 태그와 관계없이 만족되지 않습니다.

(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에서 사용 중단됨)
단순 반복자에 필요한 타입 정의를 용이하게 하는 기본 클래스
(클래스 템플릿)
반복자의 속성에 대한 통일된 인터페이스를 제공함
(클래스 템플릿)