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

履歴 編集

function template
<iterator>

std::ranges::advance(C++20)

namespace std::ranges {
  template<input_or_output_iterator I>
  constexpr void advance(I& i, iter_difference_t<I> n);     // (1)

  template<input_or_output_iterator I, sentinel_for<I> S>
  constexpr void advance(I& i, S bound);                    // (2)

  template<input_or_output_iterator I, sentinel_for<I> S>
  constexpr iter_difference_t<I> advance(I& i, iter_difference_t<I> n, S bound);  // (3)
}

概要

イテレータをn回あるいは指定された位置まで進める。

ranges::next()ranges::prev()と違い、引数として渡されたイテレータへの参照を書き換える。

引数

  • i -- 進める対象のイテレータの参照
  • n -- 進める距離
  • bound -- 進行の目的地となる位置を示すイテレータ(あるいは番兵)

事前条件

  • (1) : Ibidirectional_iteratorのモデルとならない場合、nは負数ではない
  • (2) : [i, bound)は有効な範囲である
  • (3) : 次のいずれか
    • n > 0 : [i, bound)は有効な範囲である
    • n == 0 : [i, bound)もしくは[bound, i)は有効な範囲である
    • n < 0 : [bound, i)は有効な範囲であり、Ibidirectional_iteratorのモデルであり、I, Ssame_as<I, S>のモデルとなる。

効果

  • (1) : 次のいずれかによって、イテレータへの参照in回進める(nが負数の場合は逆方向に進める)。
    • Irandom_access_iteratorのモデルとなる : i += n
    • nが正数 : in回インクリメントする
    • nが負数 : i-n回デクリメントする
  • (2) : 次のいずれかによって、イテレータへの参照iboundまで進める。
    • I, Sassignable_from<I&, S>のモデルとなる : i = std::move(bound)
    • S, Isized_sentinel_for<S, I>のモデルとなる : ranges::advance(i, bound - i)((1)に委譲)
    • それ以外の場合 : bool(i != bound) == trueである間、iをインクリメントする
  • (3) : 次のいずれかによって、イテレータへの参照iboundを超えないようにn回進める(nが負数の場合は逆方向に進める)。
    • S, Isized_sentinel_for<S, I>のモデルとなり
      • |n| >= |bound - i| : ranges::advance(i, bound)((2)に委譲)
      • |n| < |bound - i| : ranges::advance(i, n)((1)に委譲)
    • それ以外の場合で
      • nが正数 : bool(i != bound) == trueである間、iを最大n回インクリメントする
      • nが負数 : bool(i != bound) == trueである間、iを最大-n回デクリメントする

戻り値

  • (1)(2) : なし
  • (3) : 指定した距離nと実際に進めた距離との差(進めなかった距離)を返す
    • iの処理終了時と開始時の位置の差をMとして、n - Mを返す

備考

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

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

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

  auto it = std::begin(vec);

  // (1)、2つ進める
  std::ranges::advance(it, 2);

  std::cout << *it << std::endl;

  auto bound = std::next(vec.begin(), 5); // 6の位置

  // (2)、boundまで進める
  std::ranges::advance(it, bound);

  std::cout << *it << std::endl;

  auto bound2 = std::next(bound, 2); // 8の位置

  // (3)、boundまでの間で、4つ進める
  auto d = std::ranges::advance(it, 4, bound2);

  std::cout << *it << std::endl;
  std::cout << "diff : " << d << std::endl;
}

出力

3
6
8
diff : 2

バージョン

言語

  • C++20

処理系

関連項目

名前 説明
next() n回前方に進めたイテレータを返す
advance() n回イテレータを進める
ranges::next() n回あるいはboundまで前方に進めたイテレータを返す
ranges::advance() n回あるいはboundまでイテレータを進める

参照