std:: distance
|
定义于头文件
<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 抵达,则返回值可能为负。 |
(since C++11) |
复杂度
线性。
然而,若
InputIt
额外满足
LegacyRandomAccessIterator
的要求,则复杂度为常数级。
可能的实现
| 通过标签分发实现的C++98版本,已移除 constexpr 修饰符 |
|---|
namespace detail { template<class It> constexpr // 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 // 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 // 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()); } |
| 通过 if constexpr 实现的C++17版本 |
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'; // 该行为是未定义的(直到LWG940) static constexpr auto il = {3, 1, 4}; // 自C++17起,`distance`可用于常量表达式上下文 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)
|
返回迭代器与哨位之间的距离,或范围起始与末尾之间的距离
(算法函数对象) |