名前空間
変種
操作

std::advance

From cppreference.com
 
 
イテレータライブラリ
イテレータのコンセプト
イテレータのプリミティブ
アルゴリズムのコンセプトとユーティリティ
間接呼び出し可能コンセプト
共通アルゴリズム要件
(C++20)
(C++20)
(C++20)
ユーティリティ
(C++20)
イテレータアダプタ
イテレータ操作
advance
(C++11)  
(C++11)
Rangeアクセス
(C++11)(C++14)
(C++14)(C++14)  
(C++11)(C++14)
(C++14)(C++14)  
(C++17)(C++20)
(C++17)
(C++17)
 
ヘッダ <iterator> で定義
template< class InputIt, class Distance >
void advance( InputIt& it, Distance n );
(C++17まで)
template< class InputIt, class Distance >
constexpr void advance( InputIt& it, Distance n );
(C++17以降)

与えられたイテレータ itn 要素だけ進めます。

n が負の場合、イテレータは後退します。この場合、InputItLegacyBidirectionalIterator の要件を満たしている必要があります。それ以外の場合、動作は未定義です。

目次

[編集] パラメータ

it - 進めるイテレータ
n - it を進める要素数
型要件
-
InputItLegacyInputIterator の要件を満たす必要があります。

[編集] 返り値

(なし)

[編集] 計算量

線形。

ただし、InputIt がさらに LegacyRandomAccessIterator の要件を満たす場合、計算量は定数時間。

[編集] 注記

指定されたインクリメントまたはデクリメントのシーケンスが、インクリメント不能なイテレータ(終了後イテレータなど)のインクリメント、またはデクリメント不能なイテレータ(先頭イテレータまたは 特異な イテレータ)のデクリメントを必要とする場合、動作は未定義です。

[編集] 実装例

libstdc++ および libc++ の実装も参照してください。


非constexpr版
namespace detail
{
    template<class It>
    void do_advance(It& it, typename std::iterator_traits<It>::difference_type n,
                    std::input_iterator_tag)
    {
        while (n > 0)
        {
            --n;
            ++it;
        }
    }
 
    template<class It>
    void do_advance(It& it, typename std::iterator_traits<It>::difference_type n,
                    std::bidirectional_iterator_tag)
    {
        while (n > 0)
        {
            --n;
            ++it;
        }
        while (n < 0)
        {
            ++n;
            --it;
        }
    }
 
    template<class It>
    void do_advance(It& it, typename std::iterator_traits<It>::difference_type n,
                    std::random_access_iterator_tag)
    {
        it += n;
    }
} // namespace detail
 
template<class It, class Distance>
void advance(It& it, Distance n)
{
    detail::do_advance(it, typename std::iterator_traits<It>::difference_type(n),
                       typename std::iterator_traits<It>::iterator_category());
}
constexpr版
template<class It, class Distance>
constexpr void advance(It& it, Distance n)
{
    using category = typename std::iterator_traits<It>::iterator_category;
    static_assert(std::is_base_of_v<std::input_iterator_tag, category>);
 
    auto dist = typename std::iterator_traits<It>::difference_type(n);
    if constexpr (std::is_base_of_v<std::random_access_iterator_tag, category>)
        it += dist;
    else
    {
        while (dist > 0)
        {
            --dist;
            ++it;
        }
        if constexpr (std::is_base_of_v<std::bidirectional_iterator_tag, category>)
            while (dist < 0)
            {
                ++dist;
                --it;
            }
    }
}

[編集]

#include <iostream>
#include <iterator>
#include <vector>
 
int main() 
{
    std::vector<int> v{3, 1, 4};
 
    auto vi = v.begin();
    std::advance(vi, 2);
    std::cout << *vi << ' ';
 
    vi = v.end();
    std::advance(vi, -2);
    std::cout << *vi << '\n';
}

出力

4 1

[編集] 関連項目

(C++11)
イテレータをインクリメントする
(関数テンプレート) [編集]
(C++11)
イテレータをデクリメントする
(関数テンプレート) [編集]
2つのイテレータ間の距離を返す
(関数テンプレート) [編集]
イテレータを指定された距離または指定された境界まで進める
(アルゴリズム関数オブジェクト)[編集]
English 日本語 中文(简体) 中文(繁體)