std::distance
來自 cppreference.com
< cpp | 迭代器 (iterator)
定義於標頭檔案 <iterator> |
||
template< class InputIt > typename std::iterator_traits<InputIt>::difference_type |
(自 C++17 起為 constexpr) | |
返回從 first 到 last 的步數。
如果 InputIt
不是 LegacyRandomAccessIterator,並且 last 無法從 first 到達,則行為未定義。
如果 InputIt
是 LegacyRandomAccessIterator,並且 first 和 last 彼此都無法到達,則行為未定義。
目錄 |
[編輯] 引數
first | - | 指向第一個元素的迭代器 |
last | - | 指向範圍末尾的迭代器 |
型別要求 | ||
-InputIt 必須滿足 LegacyInputIterator 的要求。如果 InputIt 額外滿足 LegacyRandomAccessIterator 的要求,則操作效率更高。 |
[編輯] 返回值
從 first 到 last 所需的增量次數。
如果使用隨機訪問迭代器,並且 first 可以從 last 到達,則該值可能為負數。 |
(C++11 起) |
[編輯] 複雜度
線性。
但是,如果 InputIt
額外滿足 LegacyRandomAccessIterator 的要求,則複雜度為常數。
[編輯] 可能實現
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 到達時,措辭不明確。 | 已明確 |
[編輯] 另請參閱
按給定距離前進迭代器 (函式模板) | |
返回滿足特定條件的元素數量 (函式模板) | |
(C++20) |
返回迭代器與哨兵之間,或範圍開頭與結尾之間的距離 (演算法函式物件) |