# std::counted_iterator

< cpp‎ | iterator

定义于头文件 `<iterator>` |  |
template< std::input_or_output_iterator I > class counted_iterator; |  | (C++20 起)

`std::counted_iterator` 是表现准确同底层迭代器的迭代器适配器，除了它记录到其范围末尾的距离。此迭代器等于 std::default_sentinel 当且仅当其计数抵达零。

### 成员类型

成员类型 | 定义
`iterator_type` | `I`
`value_type` | 若 `I` 实现 `indirectly_readable` 则为 std::iter_value_t<I> ；否则不定义
`difference_type` | std::iter_difference_t<I>
`iterator_concept` | 若 I::iterator_concept 存在则为它；否则不定义
`iterator_category` | 若 I::iterator_category 存在则为它；否则不定义

### 成员函数

(构造函数) (C++20) | 构造新的迭代器适配器 (公开成员函数)
operator= (C++20) | 赋值另一迭代器适配器 (公开成员函数)
base (C++20) | 访问底层迭代器 (公开成员函数)
count (C++20) | 返回到末尾的距离 (公开成员函数)
operator*operator-> (C++20) | 访问被指向的元素 (公开成员函数)
operator[] (C++20) | 按索引访问元素 (公开成员函数)
operator++operator++(int)operator+=operator+operator--operator--(int)operator-=operator- (C++20) | 推进或回退迭代器 (公开成员函数)

### 成员对象

成员名 | 定义
`current` (私有) | `base()` 所访问的底层迭代器，名字仅用于阐释
`length` (私有) | 底层迭代器与其范围末尾的距离，名字仅用于阐释

### 非成员函数

operator==operator<=> (C++20) | 比较到末尾的距离 (函数模板)
operator==(std::default_sentinel) (C++20) | 检查到末尾的距离是否等于 `​0​` (函数模板)
operator+ (C++20) | 令迭代器前进 (函数模板)
operator- (C++20) | 计算两个迭代器适配器间的距离 (函数模板)
operator-(std::default_sentinel_t) (C++20) | 计算到末尾的有符号距离 (函数模板)
iter_move (C++20) | 转型解引用底层迭代器的结果为其所关联的右值引用类型 (函数)
iter_swap (C++20) | 交换二个底层迭代器所指向的对象 (函数模板)

### 辅助类

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

### 示例

    #include <algorithm>
    #include <iostream>
    #include <iterator>
    #include <string>
    #include <vector>
    using std::operator""s;

    void print(auto const remark, auto const& v) {
        const auto size = std::ssize(v);
        std::cout << remark << "[" << size << "] { ";
        for (auto it = std::counted_iterator{std::cbegin(v), size};
             it != std::default_sentinel; ++it) {
            std::cout << *it << ", ";
        }
        std::cout << "}\n";
    }

    int main() {
        const auto src = {"Arcturus"s, "Betelgeuse"s, "Canopus"s, "Deneb"s, "Elnath"s };
        print("src", src);
        std::vector<decltype(src)::value_type> dst;
        std::ranges::copy(std::counted_iterator{src.begin(), 3},
                          std::default_sentinel,
                          std::back_inserter(dst));
        print("dst", dst);
    }

输出：

    src[5] { Arcturus, Betelgeuse, Canopus, Deneb, Elnath, }
    dst[3] { Arcturus, Betelgeuse, Canopus, }

### 缺陷报告

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

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
P2259R1 | C++20 | 不提供成员 typedef 对 `counted_iterator` 特化 std::incrementable_traits | 添加成员 typedef 以顾及 `iterator_traits` 修正 移除了冗余的 std::incrementable_traits 特化

### 参阅

default_sentinel_t (C++20) | 用于知晓其边界的迭代器的默认哨位 (类)
views::counted (C++20) | 从迭代器和计数创建子范围 (定制点对象)
ranges::take_view views::take (C++20) | 由另一 `view` 的前 N 个元素组成的 `view` (类模板) (范围适配器对象)