std::ranges::distance
來自 cppreference.com
< cpp | 迭代器 (iterator)
定義於標頭檔案 <iterator> |
||
呼叫簽名 (Call signature) |
||
template< class I, std::sentinel_for<I> S > requires (!std::sized_sentinel_for<S, I>) |
(1) | (C++20 起) |
template< class I, std::sized_sentinel_for<std::decay_t<I>> S > constexpr std::iter_difference_t<std::decay_t<I>> |
(2) | (C++20 起) |
template< ranges::range R > constexpr ranges::range_difference_t<R> |
(3) | (C++20 起) |
1,2) 返回從 first 到 last 的步數。
3) 以有符號整數形式返回 r 的大小。
本頁描述的類函式實體是 演算法函式物件(非正式地稱為 niebloids),即
目錄 |
[編輯] 引數
first | - | 指向首元素的迭代器 |
last | - | 表示 first 所在範圍末尾的哨兵 |
r | - | 要計算距離的範圍 |
[編輯] 返回值
1) 從 first 到 last 所需的增量次數。
2) last - static_cast<const std::decay_t<I>&>(first)。
3) 如果
R
建模 ranges::sized_range,則返回 ranges::size(r);否則返回 ranges::distance(ranges::begin(r), ranges::end(r))。[編輯] 複雜度
1) 線性。
2) 常數。
3) 如果
R
建模 ranges::sized_range 或者 std::sized_sentinel_for<ranges::sentinel_t<R>, ranges::iterator_t<R>> 被建模,則複雜度是常數;否則是線性。[編輯] 可能的實現
struct distance_fn { template<class I, std::sentinel_for<I> S> requires (!std::sized_sentinel_for<S, I>) constexpr std::iter_difference_t<I> operator()(I first, S last) const { std::iter_difference_t<I> result = 0; while (first != last) { ++first; ++result; } return result; } template<class I, std::sized_sentinel_for<std::decay<I>> S> constexpr std::iter_difference_t<I> operator()(const I& first, S last) const { return last - first; } template<ranges::range R> constexpr ranges::range_difference_t<R> operator()(R&& r) const { if constexpr (ranges::sized_range<std::remove_cvref_t<R>>) return static_cast<ranges::range_difference_t<R>>(ranges::size(r)); else return (*this)(ranges::begin(r), ranges::end(r)); } }; inline constexpr auto distance = distance_fn{}; |
[編輯] 示例
執行此程式碼
#include <cassert> #include <forward_list> #include <iterator> #include <vector> int main() { std::vector<int> v{3, 1, 4}; assert(std::ranges::distance(v.begin(), v.end()) == 3); assert(std::ranges::distance(v.end(), v.begin()) == -3); assert(std::ranges::distance(v) == 3); std::forward_list<int> l{2, 7, 1}; // auto size = std::ranges::size(l); // error: not a sizable range auto size = std::ranges::distance(l); // OK, but aware O(N) complexity assert(size == 3); }
[編輯] 缺陷報告
下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。
缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
---|---|---|---|
LWG 3392 | C++20 | 過載 (1) 按值獲取迭代器,因此移動專用 具有有大小哨兵的迭代器左值被拒絕 |
添加了過載 (2) |
LWG 3664 | C++20 | LWG issue 3392 的解決方案導致ranges::distance 拒絕陣列引數 |
接受它們 |
[編輯] 參見
(C++20) |
將迭代器前進指定距離或到指定邊界 (演算法函式物件) |
(C++20)(C++20) |
返回滿足特定條件的元素數量 (演算法函式物件) |
返回兩個迭代器間的距離 (函式模板) |