std::distance
来自 cppreference.cn
定义于头文件 <iterator> |
||
template< class InputIt > typename std::iterator_traits<InputIt>::difference_type |
(constexpr since C++17) | |
返回从 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()); } |
通过 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'; // 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++ 标准。
DR | 应用于 | 已发布行为 | 正确行为 |
---|---|---|---|
LWG 940 | C++98 | 对于 first 从 last 可达的情况,措辞不明确 | 已明确 |
[编辑] 参见
按给定距离推进迭代器 (函数模板) | |
返回满足特定标准的元素数量 (函数模板) | |
(C++20) |
返回迭代器和哨兵之间,或范围的开始和结束之间的距离 (算法函数对象) |