名稱空間
變體
操作

std::ranges::distance

來自 cppreference.com
 
 
迭代器庫
迭代器概念
迭代器原語
演算法概念與工具
間接可呼叫概念
常用演算法要求
工具
迭代器介面卡
 
定義於標頭檔案 <iterator>
呼叫簽名 (Call signature)
template< class I, std::sentinel_for<I> S >

    requires (!std::sized_sentinel_for<S, I>)
constexpr std::iter_difference_t<I>

    distance( I first, S last );
(1) (C++20 起)
template< class I, std::sized_sentinel_for<std::decay_t<I>> S >

constexpr std::iter_difference_t<std::decay_t<I>>

    distance( I&& first, S last );
(2) (C++20 起)
template< ranges::range R >

constexpr ranges::range_difference_t<R>

    distance( R&& r );
(3) (C++20 起)
1,2) 返回從 firstlast 的步數。
3) 以有符號整數形式返回 r 的大小。

本頁描述的類函式實體是 演算法函式物件(非正式地稱為 niebloids),即

目錄

[編輯] 引數

first - 指向首元素的迭代器
last - 表示 first 所在範圍末尾的哨兵
r - 要計算距離的範圍

[編輯] 返回值

1)firstlast 所需的增量次數。
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 拒絕陣列引數
接受它們

[編輯] 參見

將迭代器前進指定距離或到指定邊界
(演算法函式物件)[編輯]
返回滿足特定條件的元素數量
(演算法函式物件)[編輯]
返回兩個迭代器間的距離
(函式模板) [編輯]