最終更新日時(UTC):
が更新

履歴 編集

class template
<iterator>

std::common_iterator(C++20)

namespace std {
  template<input_or_output_iterator I, sentinel_for<I> S>
    requires (!same_as<I, S> && copyable<I>)
  class common_iterator {

  private:
    variant<I, S> v_; // 説明専用メンバ変数
  };


  // incrementable_traitsにアダプトする
  template<class I, class S>
  struct incrementable_traits<common_iterator<I, S>> {
    using difference_type = iter_difference_t<I>;
  };

  // iterator_traitsにアダプトする
  template<input_iterator I, class S>
  struct iterator_traits<common_iterator<I, S>> {
    using iterator_concept = /*see below*/;
    using iterator_category = /*see below*/;  // 定義されない場合がある
    using value_type = iter_value_t<I>;
    using difference_type = iter_difference_t<I>;
    using pointer = /*see below*/;
    using reference = iter_reference_t<I>;
  };
}

概要

common_iteratorは、イテレータ型と番兵型が異なる範囲についてそれぞれをラップして、同じ範囲を表しながらイテレータ型と番兵型を共通化させるためのイテレータ/番兵アダプタである。

同じ範囲についてのイテレータ/番兵を保持して、等値比較演算子を適切に実装することで共通化を行う。

メンバ関数

名前 説明 対応バージョン
(constructor) コンストラクタ C++20
operator= 代入演算子 C++20
operator* 間接参照演算子 C++20
operator-> メンバアクセス演算子 C++20
operator++ イテレータをインクリメントする C++20

非メンバ(Hidden friends)関数

名前 説明 対応バージョン
operator== 等値比較 C++20
operator!= 非等値比較 (==により使用可能) C++20
operator- 2つのcommon_iteratorの差を求める C++20
iter_move イテレータの要素の移動 C++20
iter_swap イテレータの要素の交換 C++20

iterator_traitsの型

名前 説明 対応バージョン
iterator_concept forward_iterator_tag
ただし、Iforward_iteratorのモデルではない場合はinput_iterator_tag
C++20
iterator_category forward_iterator_tag
ただし、iterator_traits<I>::iterator_categoryderived_from<forward_iterator_tag>のモデルではない場合はinput_iterator_tag
C++20
value_type iter_value_t<I> C++20
difference_type iter_difference_t<I> C++20
pointer void
ただし、operator->が利用可能である場合はその戻り値型
C++20
reference iter_reference_t<I> C++20
  • iterator_categoryiter_difference_t<I>が組み込みの整数型の場合にのみ定義される(integer-class型の場合には定義されない)

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

// イテレータによって範囲の要素を出力する
// イテレータ型と番兵型が同一であることを前提とするレガシーな実装
template<typename I>
void iter_output(I it, I end) {
  for (;it != end; ++it) {
    std::cout << *it << std::endl;
  }
}

int main() {
  auto seq = std::views::iota(1) | std::views::take(5);

  // 範囲seqはイテレータ型と番兵型が異なっているためそのままだとエラー
  //iter_output(std::ranges::begin(seq), std::ranges::end(seq));

  // common_iteratorを通すことでイテレータ型と番兵型を合わせる
  using CI = std::common_iterator<std::ranges::iterator_t<decltype(seq)>, std::ranges::sentinel_t<decltype(seq)>>;

  auto it = CI{std::ranges::begin(seq)};
  auto end = CI{std::ranges::end(seq)};

  iter_output(it, end);
}

出力

1
2
3
4
5

バージョン

言語

  • C++20

処理系

関連項目

参照