1. 场景
业务场景使用unordered_map,每次从指定位置n(n不大于unordered_map长度)开始往后遍历。由于unordered_map没有operator+=不能像vector一样通过+=偏移到指定位置。advance可以将迭代器偏移到n个位置。
本文简单探究一下advance不同迭代器实现过程是怎样,由于advance实现依赖迭代器类型,本文还会简单介绍一下iterator_category。
2. advance 用法介绍
http://www.cplusplus.com/reference/iterator/advance/?kw=advance
Advance iterator
template <class InputIterator, class Distance>
void advance (InputIterator& it, Distance n);
Advances the iterator it by n element positions.
If it is a random-access iterator, the function uses just once operator+ or operator-. Otherwise, the function uses repeatedly the increase or decrease operator (operator++ or operator–) until n elements have been advanced.
Parameters
it
Iterator to be advanced.
InputIterator shall be at least an input iterator.
n
Number of element positions to advance.
This shall only be negative for random-access and bidirectional iterators.
Distance shall be a numerical type able to represent distances between iterators of this type.
Return value
none
3. advance源码分析
3.1 源码查看
/**
* @brief A generalization of pointer arithmetic.
* @param i An input iterator.
* @param n The "delta" by which to change @p i.
* @return Nothing.
*
* This increments @p i by @p n. For bidirectional and random access
* iterators, @p n may be negative, in which case @p i is decremented.
*
* For random access iterators, this uses their @c + and @c - operations
* and are constant time. For other %iterator classes they are linear time.
*/
template<typename _InputIterator, typename _Distance>
inline void
advance(_InputIterator& __i, _Distance __n)
{
// concept requirements -- taken care of in __advance
typename iterator_traits<_InputIterator>::difference_type __d = __n;
std::__advance(__i, __d, std::__iterator_category(__i));
}
__advance 有两个特化
template<typename _InputIterator, typename _Distance>
inline void
__advance(_InputIterator& __i, _Distance __n, input_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
while (__n--)
++__i;
}
template<typename _BidirectionalIterator, typename _Distance>
inline void
__advance(_BidirectionalIterator& __i, _Distance __