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) :
Iがbidirectional_iteratorのモデルとならない場合、nは負数ではない - (2) :
[i, bound)は有効なイテレータ範囲である - (3) : 次のいずれか
n > 0:[i, bound)は有効なイテレータ範囲であるn == 0:[i, bound)もしくは[bound, i)は有効なイテレータ範囲であるn < 0:[bound, i)は有効なイテレータ範囲であり、Iはbidirectional_iteratorのモデルであり、I, Sはsame_as<I, S>のモデルとなる。
効果
- (1) : 次のいずれかによって、イテレータへの参照
iをn回進める(nが負数の場合は逆方向に進める)。Iがrandom_access_iteratorのモデルとなる :i += nnが正数 :iをn回インクリメントするnが負数 :iを-n回デクリメントする
- (2) : 次のいずれかによって、イテレータへの参照
iをboundまで進める。I, Sがassignable_from<I&, S>のモデルとなる :i = std::move(bound)S, Iがsized_sentinel_for<S, I>のモデルとなる :ranges::advance(i, bound - i)((1)に委譲)- それ以外の場合 :
bool(i != bound) == trueである間、iをインクリメントする
- (3) : 次のいずれかによって、イテレータへの参照
iをboundを超えないようにn回進める(nが負数の場合は逆方向に進める)。S, Iがsized_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
処理系
- Clang: ??
- GCC: 10.1 ✅
- Visual C++: 2019 Update 5 ✅
関連項目
| 名前 | 説明 |
|---|---|
next() |
n回前方に進めたイテレータを返す |
prev() |
n回後方に進めたイテレータを返す |
advance() |
n回イテレータを進める |
ranges::next() |
n回あるいはboundまで前方に進めたイテレータを返す |
rangse::prev() |
n回後方に進めたイテレータを返す |