# 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

< cpp‎ | iterator

定义于头文件 `<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) 。

顾名思义，迭代器分类标签可以用以标示某个迭代器的分类，可以根据这一分类所要求的特性来选择最优算法。

### 迭代器概念 对每个 `input_iterator` 类型 `It` ，可以声明 It::iterator_concept （若 std::iterator_traits<It> 从主模板生成）或 std::iterator_traits<It>::iterator_concept （若 std::iterator_traits<It> 被特化）为这些标签之一的别名，以指示 `It` 有意实现的最强迭代器概念。 `input_iterator_tag` 对应 `input_iterator` 。 `forward_iterator_tag` 对应 `forward_iterator` 。 `bidirectional_iterator_tag` 对应 `bidirectional_iterator` 。 `random_access_iterator_tag` 对应 `random_access_iterator` 。 `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 起)

### 示例

如果需要根据迭代器分类标签选择算法，常用做法是使用分发函数（也可以通过 std::enable_if 实现）

    #include <iostream>
    #include <vector>
    #include <list>
    #include <iterator>

    // 经常把实现细节隐藏于细致的命名空间
    namespace implementation_details {
    template< class BDIter >
    void alg(BDIter, BDIter, std::bidirectional_iterator_tag)
    {
        std::cout << "alg() called for bidirectional iterator\n";
    }

    template <class RAIter>
    void alg(RAIter, RAIter, std::random_access_iterator_tag)
    {
        std::cout << "alg() called for random-access iterator\n";
    }
    } // namespace implementation_details

    template< class Iter >
    void alg(Iter first, Iter last)
    {
        alg(first, last,
            typename std::iterator_traits<Iter>::iterator_category());
    }

    int main()
    {
        std::vector<int> v;
        alg(v.begin(), v.end());

        std::list<int> l;
        alg(l.begin(), l.end());

    //    std::istreambuf_iterator<char> i1(std::cin), i2;
    //    alg(i1, i2); // 编译错误：无调用的匹配函数
    }

输出：

    alg() called for random-access iterator
    alg() called for bidirectional iterator

### 参阅

iterator (C++17 中弃用) | 用于简化简单的迭代器的必要类型定义的基类 (类模板)
iterator_traits | 为迭代器各项性质提供统一接口 (类模板)