最終更新日時(UTC): 2018年10月16日 07時26分39秒
Akira Takahashi が更新

履歴 編集

function template
<iterator>

# std::advance

    namespace std {
      template <class InputIterator, class Distance>
      void advance(InputIterator& i, Distance n);               // C++03

      template <class InputIterator, class Distance>
      constexpr void advance(InputIterator& i, Distance n);     // C++17
    }

## 概要

イテレータを`n`回進める。

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

## 要件

双方向イテレータもしくはランダムアクセスイテレータの場合のみ、`n`が負数であることを許可する。

## 効果

イテレータへの参照`i`を`n`回進める(`n`が負数の場合は逆方向に進める)。

## 戻り値

なし

## 計算量

- 入力イテレータ、前方向イテレータ ： `n`回のインクリメント
- 双方向イテレータ： `n`回のインクリメント、もしくはデクリメント
- ランダムアクセスイテレータ： O(1)

## 例

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

    int main()
    {
      std::vector<int> v = {3, 1, 4, 2, 5};

      decltype(v)::iterator i = v.begin();
      std::advance(i, 3); // イテレータiを3回進める

      std::cout << *i << std::endl;
    }

### 出力

    2

## 実装例

    // 入力イテレータ(or 前方向イテレータ)
    template <class InputIterator, class Distance>
    void advance_impl(InputIterator& i, Distance n, std::input_iterator_tag)
    {
      assert(n >= 0);

      for (; 0 < n; --n) { ++i; }
    }

    // 双方向イテレータ
    template <class BidirectionalIterator, class Distance>
    void advance_impl(BidirectionalIterator& i, Distance n, std::bidirectional_iterator_tag)
    {
      if (n > 0) {
        for (; 0 < n; --n) { ++i; }
      }
      else {
        for (; n < 0; ++n) { --i; }
      }
    }

    // ランダムアクセスイテレータ
    template <class RandomAccessIterator, class Distance>
    void advance_impl(RandomAccessIterator& i, Distance n, std::random_access_iterator_tag)
    {
      i += n;
    }

    template <class Iterator, class Distance>
    void advance(Iterator& i, Distance n)
    {
      advance_impl(i, n,
              typename std::iterator_traits<Iterator>::iterator_category());
              // イテレータのカテゴリごとに最適な実装を選択させる
    }

## 関連項目

名前 | 説明
--- | ---
`next()` | `n`回前方に進めたイテレータを返す
`prev()` | `n`回後方に進めたイテレータを返す

## 参照

- P0031R0 A Proposal to Add Constexpr Modifiers to `reverse_iterator`, `move_iterator`, `array` and Range Access