最終更新日時: 2026年02月26日 13時20分38秒 (JST)
Akira Takahashi が更新

履歴 編集

function
<iterator>

# std::common_iterator::operator==(C++20)

    namespace std {
      template<input_or_output_iterator I, sentinel_for<I> S>
      class common_iterator {

        template<class I2, sentinel_for<I> S2>
          requires sentinel_for<S, I2>
        friend bool operator==(const common_iterator& x, const common_iterator<I2, S2>& y);   // (1)

        template<class I2, sentinel_for<I> S2>
          requires sentinel_for<S, I2> && equality_comparable_with<I, I2>
        friend bool operator==(const common_iterator& x, const common_iterator<I2, S2>& y);   // (2)
      };
    }

## 概要

2つの`common_iterator`オブジェクトが同じ要素を指しているかを判定する。

## 堅牢化された事前条件

`x.v_.valueless_by_exception()`、`y.v_.valueless_by_exception()`はどちらも`false`であること。

## 戻り値

`I, S`（`I2, S2`）の値のどちらかを`variant<I, S>`型のメンバ変数`v_`に保持しており、`i = x.v_.index()`、`j = y.v_.index()`として

- (1)
  - `i == j`の場合 : `true`
  - それ以外の場合 : `get<i>(x.v_) == get<j>(y.v_)`
- (2)
  - `i, j`がどちらも`1`の場合 : `true`
  - それ以外の場合 : `get<i>(x.v_) == get<j>(y.v_)`

## 備考

C++20以降、これらの演算子により以下の演算子が使用可能になる（制約は使用する`==`に準ずる）。

    template<class I2, sentinel_for<I> S2>
    friend bool operator==(const common_iterator<I2, S2>& y, const common_iterator& x);

    template<class I2, sentinel_for<I> S2>
    friend bool operator!=(const common_iterator& x, const common_iterator<I2, S2>& y);

    template<class I2, sentinel_for<I> S2>
    friend bool operator!=(const common_iterator<I2, S2>& y, const common_iterator& x);

## 例

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

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

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

      CI ci{std::ranges::begin(seq)};
      CI ce{std::ranges::end(seq)};
      auto ci2 = ci++;

      std::cout << std::boolalpha;

      std::cout << (ci == ci2) << std::endl;
      std::cout << (ci == ce) << std::endl;

      // ==から導出される!=
      std::cout << (ci != ci2) << std::endl;
      std::cout << (ci != ce) << std::endl;
    }

### 出力

    false
    false
    true
    true

## バージョン

### 言語

- C++20

### 処理系

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

## 参照

- P0896R4 The One Ranges Proposal (was Merging the Ranges TS)
- P3697R1 Minor additions to C++26 standard library hardening
- P3878R1 Standard library hardening should not use the 'observe' semantic