最終更新日時: 2025年08月31日 19時06分36秒 (JST)
Raclamusi が更新

履歴 編集

function template
<iterator>

# std::ranges::distance(C++20)

    namespace std::ranges {
      template<input_or_output_iterator I, sentinel_for<I> S>
      constexpr iter_difference_t<I> distance(I first, S last);   // (1)

      template<range R>
      constexpr range_difference_t<R> distance(R&& r);            // (2)
    }

## 概要

イテレータ間あるいは範囲の距離を求める。

## 引数

- `first` -- 距離を求めたい範囲の開始イテレータ
- `last` -- 距離を求めたい範囲の終端イテレータ（あるいは番兵）
- `r` -- 範囲を示すrangeオブジェクト

## 事前条件

- (1) : 次のいずれか
  - `[first, last)`は有効なイテレータ範囲である
  - `[last, first)`は有効なイテレータ範囲であり、`S, I`は`same_as<S, I>`および`sized_sentinel_for<S, I>`のモデルとなる

## 効果

- (1) : 次のいずれかによって、`first`から`last`までの距離を求める。
  - `S, I`が`sized_sentinel_for<S, I>`のモデルとなる : `return (last - first)`
  - それ以外の場合 : `first`から`last`に到達するのに必要なインクリメントの回数を返す。
- (2) : 次のいずれかによって、範囲の長さを求める。
  - `R`が`sized_range<R>`のモデルとなる : `return static_cast<range_difference_t<R>>(ranges::size(r));`
  - それ以外の場合 : `return ranges::distance(ranges::begin(r), ranges::end(r))` （(1)に委譲）

## 戻り値

- (1) : `first`から`last`までの距離
- (2) : `r`の範囲の長さ（先頭から終端までの距離）

## 備考

この関数テンプレートは通常の名前探索で発見されている場合にADLを無効化する。詳しくは「ADLを無効にする関数定義」を参照のこと。

## 例

    #include <iostream>
    #include <iterator>
    #include <vector>
    #include <forward_list>

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

      auto it = std::begin(vec);

      // (1) イテレータ間距離を求める
      std::cout << std::ranges::distance(it, std::end(vec)) << std::endl;
      std::cout << std::ranges::distance(it, std::next(it, 5)) << std::endl;
      std::cout << std::ranges::distance(std::next(it, 5), it) << std::endl;

      // (2) rangeの長さを求める
      std::cout << std::ranges::distance(vec) << std::endl;
      std::cout << std::ranges::distance(fl) << std::endl;
    }

### 出力

    10
    5
    -5
    10
    7

## バージョン

### 言語

- C++20

### 処理系

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

## 関連項目

- `distance()`

## 参照

- P0896R4 The One Ranges Proposal (was Merging the Ranges TS)