std::ranges:: distance
|
定义于头文件
<iterator>
|
||
|
调用签名
|
||
|
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 起) |
本页面描述的函数式实体是 算法函数对象 (非正式称为 niebloids ),即:
目录 |
参数
| first | - | 指向首个元素的迭代器 |
| last | - | 表示范围结尾的哨兵 first 所指向的迭代器范围 |
| r | - | 待计算距离的范围 |
返回值
R
满足
ranges::
sized_range
概念,则返回
ranges::
size
(
r
)
;否则返回
ranges
::
distance
(
ranges::
begin
(
r
)
,
ranges::
end
(
r
)
)
。
复杂度
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); // 错误:不是可确定大小的范围 auto size = std::ranges::distance(l); // 可行,但需注意 O(N) 时间复杂度 assert(size == 3); }
缺陷报告
下列行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
| 缺陷报告 | 适用标准 | 发布行为 | 正确行为 |
|---|---|---|---|
| LWG 3392 | C++20 |
重载
(1)
按值获取迭代器,因此拒绝具有大小标记的
仅移动迭代器左值 |
增加重载 (2) |
| LWG 3664 | C++20 |
LWG 3392
的解决方案导致
ranges::distance
拒绝数组参数
|
接受数组参数 |
参见
|
(C++20)
|
将迭代器前进给定距离或至指定边界
(算法函数对象) |
|
(C++20)
(C++20)
|
返回满足特定条件的元素数量
(算法函数对象) |
|
返回两个迭代器之间的距离
(函数模板) |