# std::iterator_traits<std::counted_iterator>

< cpp‎ | iterator‎ | counted iterator

定义于头文件 `<iterator>` |  |
template< std::input_iterator I > requires /* see below */ struct iterator_traits<std::counted_iterator<I>> : std::iterator_traits<I> { using pointer = std::conditional_t<std::contiguous_iterator<I>, std::add_pointer_t<std::iter_reference_t<I>>, void>; }; |  | (C++20 起)

从定制（从标准部分特化或程序定义特化生成）的 std::iterator_traits<I> 继承属性，调整成员类型 `pointer` ，其中 `I` 实现 `input_iterator` 。

值得注意的是， `iterator_concept` （若存在）和 `iterator_category` （若存在）从 std::iterator_traits<I> 继承。

requires 子句中的条件为 true 当且仅当 std::iterator_traits<I> 不从主模板生成。

### 注解

P2259R1 前，即使 std::iterator_traits<I> 从主模板生成也使用此特化。结果在针对迭代器概念（例如 `forward_iterator` ）测试 std::counted_iterator<I> 时， /*ITER_CONCEPT*/ 的确定过程不考虑 `I::iterator_concept` ，从而 std::counted_iterator<I> 有时错误地表现为它无法实现该概念。此错误行为在 10.4 前的 libstdc++ 与 VS 2022 17.0 Preview 3 前的 MSVC STL 中实现。

标准库对指针类型、 std::counted_iterator 及 std::common_iterator 提供 std::iterator_traits 的部分特化。

### 示例

    #include <iterator>
    #include <type_traits>
    #include <list>
    #include <vector>

    int main() {
        std::vector v{1,2,3,4};
        std::list l{1,2,3,4};
        std::counted_iterator iv{v.begin(), 3};
        std::counted_iterator il{l.begin(), 3};
        static_assert(std::is_same<int*, std::iterator_traits<decltype(iv)>::pointer>());
        static_assert(std::is_same<void, std::iterator_traits<decltype(il)>::pointer>());
    }

### 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
P2259R1 | C++20 | 无 requires 子句 无条件定义 `pointer` 为 void | 添加约束

### 参阅

iterator_traits | 为迭代器各项性质提供统一接口 (类模板)