名稱空間
變體
操作

std::advance

來自 cppreference.com
 
 
迭代器庫
迭代器概念
迭代器原語
演算法概念與工具
間接可呼叫概念
常用演算法要求
(C++20)
(C++20)
(C++20)
工具
(C++20)
迭代器介面卡
迭代器操作
advance
(C++11)  
(C++11)
範圍訪問
(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 起)

將給定迭代器 it 增加 n 個元素。

n 為負,則迭代器遞減。在此情況下,InputIt 必須滿足 LegacyBidirectionalIterator 的要求,否則行為未定義。

目錄

[編輯] 引數

it - 要前進的迭代器
n - it 應前進的元素數量
型別要求
-
InputIt 必須滿足 LegacyInputIterator 的要求。

[編輯] 返回值

(無)

[編輯] 複雜度

線性。

然而,如果 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)
遞減迭代器
(函式模板) [編輯]
返回兩個迭代器間的距離
(函式模板) [編輯]
將迭代器前進指定距離或到指定邊界
(演算法函式物件)[編輯]