名稱空間
變體
操作

std::distance

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

typename std::iterator_traits<InputIt>::difference_type

    distance( InputIt first, InputIt last );
(自 C++17 起為 constexpr)

返回從 firstlast 的步數。

如果 InputIt 不是 LegacyRandomAccessIterator,並且 last 無法從 first 到達,則行為未定義。

如果 InputItLegacyRandomAccessIterator,並且 firstlast 彼此都無法到達,則行為未定義。

目錄

[編輯] 引數

first - 指向第一個元素的迭代器
last - 指向範圍末尾的迭代器
型別要求
-
InputIt 必須滿足 LegacyInputIterator 的要求。如果 InputIt 額外滿足 LegacyRandomAccessIterator 的要求,則操作效率更高。

[編輯] 返回值

firstlast 所需的增量次數。

如果使用隨機訪問迭代器,並且 first 可以從 last 到達,則該值可能為負數。

(C++11 起)

[編輯] 複雜度

線性。

但是,如果 InputIt 額外滿足 LegacyRandomAccessIterator 的要求,則複雜度為常數。

[編輯] 可能實現

另請參閱 libstdc++libc++ 中的實現。

C++98 透過標籤分派的實現,移除 constexpr
namespace detail
{
    template<class It>
    constexpr // required since C++17
    typename std::iterator_traits<It>::difference_type 
        do_distance(It first, It last, std::input_iterator_tag)
    {
        typename std::iterator_traits<It>::difference_type result = 0;
        while (first != last)
        {
            ++first;
            ++result;
        }
        return result;
    }
 
    template<class It>
    constexpr // required since C++17
    typename std::iterator_traits<It>::difference_type 
        do_distance(It first, It last, std::random_access_iterator_tag)
    {
        return last - first;
    }
} // namespace detail
 
template<class It>
constexpr // since C++17
typename std::iterator_traits<It>::difference_type 
    distance(It first, It last)
{
    return detail::do_distance(first, last,
                               typename std::iterator_traits<It>::iterator_category());
}
C++17 透過 if constexpr 的實現
template<class It>
constexpr typename std::iterator_traits<It>::difference_type
    distance(It first, It last)
{
    using category = typename std::iterator_traits<It>::iterator_category;
    static_assert(std::is_base_of_v<std::input_iterator_tag, category>);
 
    if constexpr (std::is_base_of_v<std::random_access_iterator_tag, category>)
        return last - first;
    else
    {
        typename std::iterator_traits<It>::difference_type result = 0;
        while (first != last)
        {
            ++first;
            ++result;
        }
        return result;
    }
}

[編輯] 示例

#include <iostream>
#include <iterator>
#include <vector>
 
int main() 
{
    std::vector<int> v{3, 1, 4};
    std::cout << "distance(first, last) = "
              << std::distance(v.begin(), v.end()) << '\n'
              << "distance(last, first) = "
              << std::distance(v.end(), v.begin()) << '\n';
              // the behavior is undefined (until LWG940)
 
    static constexpr auto il = {3, 1, 4};
    // Since C++17 `distance` can be used in constexpr context.
    static_assert(std::distance(il.begin(), il.end()) == 3);
    static_assert(std::distance(il.end(), il.begin()) == -3);
}

輸出

distance(first, last) = 3
distance(last, first) = -3

[編輯] 缺陷報告

下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
LWG 940 C++98 first 可以從 last 到達時,措辭不明確。 已明確

[編輯] 另請參閱

按給定距離前進迭代器
(函式模板) [編輯]
返回滿足特定條件的元素數量
(函式模板) [編輯]
返回迭代器與哨兵之間,或範圍開頭與結尾之間的距離
(演算法函式物件)[編輯]