iterator
- 本文代码根据 GNU ISO C++ Library 所含库文件整理,同时参考了 Microsoft Visual Studio Community 2017 版本 15.8.4 的库文件源代码和《STL 源码分析》(侯捷著)中的第 3 章内容
- 本文暂时略去了源文件中的异常处理代码
iterator
概述
- 每一种 STL 容器都有专属的迭代器,避免暴露容器的内部结构
iterator
的种类标记
- 迭代器通常分为五种:
input_iterator
, output_iterator
, forward_iterator
, bidirectional_iterator
, random_access_iterator
- 种类标记必须是类型,以便根据不同的类型重载函数
struct input_iterator_tag {
};
struct output_iterator_tag {
};
struct forward_iterator_tag : public input_iterator_tag {
};
struct bidirectional_iterator_tag : public forward_iterator_tag {
};
struct random_access_iterator_tag : public bidirectional_iterator_tag {
};
iterator
的关联类型
template <typename Category, typename T, typename Distance = ptrdiff_t,
typename Pointer = T*, typename Reference = T&>
struct iterator
{
typedef Category iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
};
iterator
的类型萃取器
template <typename It, typename = __void_t<>>
struct __iterator_traits {
};
template <typename It>
struct __iterator_traits<It, __void_t<typename It::iterator_category,
typename It::value_type,
typename It::difference_type,
typename It::pointer,
typename It::reference>>
{
typedef typename It::iterator_category iterator_category;
typedef typename It::value_type value_type;
typedef typename It::difference_type difference_type;
typedef typename It::pointer pointer;
typedef typename It::reference reference;
};
template <typename It>
struct iterator_traits : public __iterator_traits<It> {
};
template <typename T>
struct iterator_traits<T*>
{
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
};
template <typename T>
struct iterator_traits<const T*>
{
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef const T* pointer;
typedef const T& reference;
};
template <typename It>
inline constexpr typename iterator_traits<It>::iterator_category
__iterator_category(const It&)
{
return typename iterator_traits<It>::iterator_category(); }
iterator
种类标记和萃取器的使用
根据不同种类的 iterator
设计不同的 distance()
函数
template <typename InputIterator>
inline constexpr typename iterator_traits<InputIterator>::difference_type
__distance(InputIterator first, InputIterator last, input_iterator_tag)
{
typename iterator_traits<InputIterator>::difference_type n = 0;
while (first != last)
{
++first;
++n
}
return n;
}
template <typename RandomAccessIterator>
inline constexpr typename iterator_traits<RandomAccessIterator>::difference_type
__distance(RandomAccessIterator first, RandomAccessIterator last, random_access_iterator_tag)
{
return last - first;
}
template <typename InputIterator>
inline constexpr typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last)
{
return __distance(first, last, __iterator_category(first)); }
根据不同种类的 iterator
设计不同的 advance()
函数
template <typename InputIterator, typename Distance>
inline constexpr void __advance(InputIterator& it, Distance n, input_iterator_tag)
{
assert(n >= 0);
while (n--) ++it;
}
template <typename BidirectionalIterator, typename Distance>
inline constexpr void __advance(BidirectionalIterator& it, Distance n, bidirectional_iterator_tag)
{
if (n > 0) while (n--) ++it;
else while (n++) --it;
}
template <typename RandomAccessIterator, typename Distance>
inline constexpr void __advance(RandomAccessIterator& it, Distance n, random_access_iterator_tag)
{
it += n;
}
template <typename InputIterator, typename Distance>
inline constexpr void __advance(InputIterator& it, Distance n)
{
__advance(it, n, __iterator_category(it)); }
next()
和 prev()
template <typename ForwardIterator>
inline constexpr ForwardIterator
next