# std::iterator_traits

< cpp‎ | iterator

定义于头文件 `<iterator>` |  |
template< class Iter > struct iterator_traits; |  |
template< class T > struct iterator_traits<T*>; |  |
template< class T > struct iterator_traits<const T*>; |  | (C++20 中移除)

`std::iterator_traits` 是类型特征类，提供面对老式迭代器 (LegacyIterator) 类型的统一接口。这使得可以仅通过迭代器实现算法。

能对用户定义的迭代器特化模板，使得即使不提供通常的 typedef 也能从迭代器取得信息。

用户定义特化可以定义成员类型 `iterator_concept` 为迭代器类别标签之一，以指示遵从该迭代器概念。 | (C++20 起)

### 模版形参

Iter | - | 需要取得与之相关属性的迭代器类型

### 成员类型

成员类型 | 定义
`difference_type` | `Iter::difference_type`
`value_type` | `Iter::value_type`
`pointer` | `Iter::pointer`
`reference` | `Iter::reference`
`iterator_category` | `Iter::iterator_category`

若 `Iter` 没有全部五个成员类型 `difference_type` 、 `value_type` 、 `pointer` 、 `reference` 及 `iterator_category` ，则此模板无任何有那些名称的成员（ std::iterator_traits 对 SFINAE 友好） | (C++17 起) (C++20 前)
若 `Iter` 无 `pointer` ，但拥有全部其他四个成员类型，则按如下方式声明成员类型：
成员类型 | 定义
`difference_type` | `Iter::difference_type`
`value_type` | `Iter::value_type`
`pointer` | `void`
`reference` | `Iter::reference`
`iterator_category` | `Iter::iterator_category`
否则，若 `Iter` 满足仅为说明的概念 `__LegacyInputIterator` ，则按如下方式声明成员类型：
成员类型 | 定义
`difference_type` | std::incrementable_traits<Iter>::difference_type
`value_type` | std::indirectly_readable_traits<Iter>::value_type
`pointer` | 若合法则为 `Iter::pointer` ，否则若合法则为 decltype(​std::declval<Iter&>().operator->()) ，否则为 `void`
`reference` | 若合法则为 `Iter::reference` ，否则为 std::iter_reference_t<Iter>
`iterator_category` | 若合法则为 `Iter::iterator_category` ， 否则若 `Iter` 满足 `__LegacyRandomAccessIterator` 则为 std::random_access_iterator_tag ， 否则若 `Iter` 满足 `__LegacyBidirectionalIterator` 则为 std::bidirectional_iterator_tag ， 否则若 `Iter` 满足 `__LegacyForwardIterator` 则为 std::forward_iterator_tag ， 否则为 std::input_iterator_tag
否则，若 `Iter` 满足仅为说明的概念 `__LegacyIterator` ，则按如下方式声明成员类型：
成员类型 | 定义
`difference_type` | 若合法则为 std::incrementable_traits<Iter>::difference_type ，否则为 `void`
`value_type` | `void`
`pointer` | `void`
`reference` | `void`
`iterator_category` | `std::output_iterator_tag`
否则，此模板无任何有这些名称的成员此模板无任何有那些名称的成员（ std::iterator_traits 对 SFINAE 友好）。 | (C++20 起)

### 特化

如果要把用户提供的类型作为迭代器使用，该类型特征可以针对这一类型进行特化。标准库中提供了针对指针类型 `T *` 的两种偏特化，使得可以在任何需要迭代器的算法里使用裸指针。

标准库亦提供对一些标准迭代器适配器的特化。 | (C++20 起)

#### `T *` 特化成员类型

仅若 std::is_object_v<T> 为 `true` 才特化。 | (C++20 起)

成员类型 | 定义
`difference_type` | std::ptrdiff_t
`value_type` | `T` (C++20 前)std::remove_cv_t<T> (C++20 起)
`pointer` | `T*`
`reference` | `T&`
`iterator_category` | std::random_access_iterator_tag
`iterator_concept`(C++20) | std::contiguous_iterator_tag

#### `const T *` 特化成员类型
成员类型 | 定义
`difference_type` | std::ptrdiff_t
`value_type` | `T`
`pointer` | `const T*`
`reference` | `const T&`
`iterator_category` | std::random_access_iterator_tag
| (C++20 前)

#### 对库类型的特化

std::iterator_traits<std::common_iterator> (C++20) | 对 std::counted_iterator 类型的属性提供均一的接口 (类模板特化)
std::iterator_traits<std::counted_iterator> (C++20) | 对 std::counted_iterator 类型的属性提供均一的接口 (类模板特化)

### 示例

下列使用展示对双向迭代器的通用 `reverse()` 实现

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

    template<class BidirIt>
    void my_reverse(BidirIt first, BidirIt last)
    {
        typename std::iterator_traits<BidirIt>::difference_type n = std::distance(first, last);
        --n;
        while(n > 0) {
            typename std::iterator_traits<BidirIt>::value_type tmp = *first;
            *first++ = *--last;
            *last = tmp;
            n -= 2;
        }
    }

    int main()
    {
        std::vector<int> v{1, 2, 3, 4, 5};
        my_reverse(v.begin(), v.end());
        for (int n : v) {
            std::cout << n << ' ';
        }
        std::cout << '\n';

        std::list<int> l{1, 2, 3, 4, 5};
        my_reverse(l.begin(), l.end());
        for (auto n : l) {
            std::cout << n << ' ';
        }
        std::cout << '\n';

        int a[] = {1, 2, 3, 4, 5};
        my_reverse(a, a+5);
        for (int i=0; i<5; ++i) {
            std::cout << a[i] << ' ';
        }
        std::cout << '\n';

    //    std::istreambuf_iterator<char> i1(std::cin), i2;
    //    my_reverse(i1, i2); // 编译错误

    }

输出：

    5 4 3 2 1
    5 4 3 2 1
    5 4 3 2 1

### 参阅

iterator (C++17 中弃用) | 用于简化简单的迭代器的必要类型定义的基类 (类模板)
input_iterator_tag output_iterator_tag forward_iterator_tag bidirectional_iterator_tag random_access_iterator_tag contiguous_iterator_tag (C++20) | 用于指示迭代器类别的空类类型 (类)