最終更新日時: 2025年07月09日 00時33分39秒 (JST)
Akira Takahashi が更新

履歴 編集

class template
<iterator>

# std::counted_iterator(C++20)

    namespace std {
      template<input_or_output_iterator I>
      class counted_iterator {

      private:
        I current = I();                  // 説明専用メンバ変数
        iter_difference_t<I> length = 0;  // 説明専用メンバ変数
      };

      // iterator_traitsにアダプトする
      template<input_iterator I>
        requires same_as<ITER_TRAITS(I), iterator_traits<I>>
      struct iterator_traits<counted_iterator<I>> : iterator_traits<I> {
        using pointer = conditional_t<contiguous_iterator<I>, add_pointer_t<iter_reference_t<I>>, void>;
      };
    }

## 概要

`counted_iterator`は、イテレータをラップしてそこから指定されたカウント数の範囲を表現するイテレータアダプタである。

イテレータを受け取る汎用アルゴリズムにおいて、終了位置を事前に知ることなくある位置から任意の個数の要素の範囲を表現し、操作するのに利用できる。

`counted_iterator`は指定されたカウント数の範囲内でのみ進行可能である事を除けば、元のイテレータと同じ動作をする。

## メンバ関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`(constructor)` | コンストラクタ | C++20
`operator=` | 代入演算子 | C++20
`base` | 元のイテレータを取得する | C++20
`count` | 代入演算子 | C++20
`operator*` | 間接参照演算子 | C++20
`operator->` | メンバアクセス演算子 | C++20
`operator++` | イテレータをインクリメントする | C++20
`operator--` | イテレータをデクリメントする | C++20
`operator+` | イテレータを進める | C++20
`operator+=` | イテレータ自身を進める | C++20
`operator-` | イテレータを逆に進める | C++20
`operator-=` | イテレータ自身を逆に進める | C++20
`operator[]` | 任意の位置にランダムアクセスする | C++20

## 非メンバ（Hidden friends）関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`operator-` | 2つの`counted_iterator`の差を求める | C++20
`operator+` | イテレータを進める | C++20
`operator==` | 等値比較 | C++20
`operator!=` | 非等値比較 (`==`により使用可能) | C++20
`operator<=>` | 三方比較 | C++20
`operator<` | 左辺が右辺より小さいかの判定を行う (`<=>`により使用可能) | C++20
`operator<=` | 左辺が右辺以下かの判定を行う (`<=>`により使用可能) | C++20
`operator>` | 左辺が右辺より大きいかの判定を行う (`<=>`により使用可能) | C++20
`operator>=` | 左辺が右辺以上かの判定を行う (`<=>`により使用可能) | C++20
`iter_move` | イテレータの要素の移動 | C++20
`iter_swap` | イテレータの要素の交換 | C++20

## メンバ型

名前 | 説明 | 対応バージョン
--- | --- | ---
`iterator_type` | `I` | C++20
`value_type` | `iter_value_t<I>`※1 | C++20
`difference_type` | `iter_difference_t<I>` | C++20
`iterator_concept` | `typename I::iterator_concept`※2 | C++20
`iterator_category` | `typename I::iterator_category`※2 | C++20

- ※1 `I`が`indirectly_readable`のモデルである場合にのみ定義される
- ※2 どちらも、対応するメンバ型が定義されている場合にのみ定義される

## 例

    #include <iostream>
    #include <iterator>
    #include <ranges>
    #include <vector>

    int main() {
      std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

      std::counted_iterator ci{std::ranges::begin(vec) + 3, 5};

      // 既存のシーケンスの部分範囲をイテレートする
      for (; ci != std::default_sentinel; ++ci) {
        std::cout << *ci << " ";
      }

      std::cout << '\n';

      // subrangeと共に用いて範囲forでイテレートする
      for (auto n : std::ranges::subrange{std::counted_iterator{std::ranges::begin(vec), 5}, std::default_sentinel}) {
        std::cout << n << " ";
      }
    }

### 出力

    4 5 6 7 8
    1 2 3 4 5

## バージョン

### 言語

- C++20

### 処理系

- Clang: ??
- GCC: 10.1 ✅
- Visual C++: 2019 Update 8 ✅

## 関連項目

- `views::counted`
- `take_view`

## 参照

- P0896R4 The One Ranges Proposal (was Merging the Ranges TS)
- Hidden Friends - yohhoyの日記
- P2259R1 Repairing input range adaptors and `counted_iterator`