置的删除操作都会使得整个迭代器失效。
使list/map/set迭代器失效的操作
由于list/map/set容器内的元素都是通过指针连接的,list实现的数据结构是双向链表,而map/set实现的数据结构是红黑树,故这些容器的插入和删除操作都只需更改指针的指向,不会移动容器内的元素,故在容器内增加元素时,不会使任何迭代器失效,而在删除元素时,仅仅会使得指向被删除的迭代器失效。
再回忆下find函数,find函数前两个形参都是输入迭代器类型,这两个迭代器并不是某个容器特有的迭代器,而是一个一般的迭代器,可将所有标准库容器内部的迭代器视为形参所对应迭代器类的派生类。下面我们透过stl中迭代器的实现代码来分析迭代器的实现方法.
#include
#include
//ptrdiff_t对应的头文件 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{};//随机访问迭代器 //std::iterator,标准迭代器的类模板 template
struct iterator//迭代器包含五个常用属性 { typedef Category iterator_category;//迭代器的类型,五种之一 typedef T value_type;//迭代器所指向的元素的类型 typedef Distance difference_type;//两个迭代器的差值 typedef Pointer pointer;//迭代器的原始指针 typedef Reference reference;//迭代器所指向元素的引用 }; //定义iterator_traits,用于提取迭代器的属性,该类的对象不应该让用户看到 template
struct iterator_traits { //下面的操作相当于一个递归的操作,用于递归提取原始指针的相关值 typedef typename Iterator::iterator_category iterator_category; typedef typename Iterator::value_type value_type; typedef typename Iterator::difference_type difference_type; typedef typename Iterator::pointer pointer; typedef typename Iterator::reference reference; }; //针对原始指针的偏特化版本 template
struct iterator_traits
{ //相当于递归终止条件 typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t diffrence_type; typedef T* pointer; typedef T& reference; }; //针对指向常用的原始指针设计的偏特化版本 template
struct iterator_traits
{ typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t diffrence_type; typedef const T * pointer;//重点在这里 typedef const T & reference;//还有这里 }; //定义两个迭代器的差值类型的函数distance_type template
inline typename iterator_traits
::difference_type * distance_type(const Iterator&) { return static_cast
::difference_type *>(0); } //获取迭代器的value_type函数 template
inline typename iterator_traits
::value_type * value_type(const Iterator&) { return static_cast
::value_type*>(0); } //求两个一般迭代器之间的距离的函数_distance,供distance函数分类调用 template
inline typename iterator_traits
::difference_type _distance(InputIterator first,InputIterator last,input_iterator_tag) { typename iterator_traits
::difference_type n=0; while(first!=last) { ++first; ++n; } return n; } //求两个随机访问迭代器之间的距离的函数_distance,供distance函数分类调用 template
inline typename iterator_traits
::difference_type _distance(RandomAccessIterator first,RandomAccessIterator last, random_access_iterator_tag) { return last-first; } //自适应地调用distance函数 template
inline typename iterator_traits
::difference_type distance(InputIterator first,InputIterator last) { typedef typename iterator_traits
::iterator_category category; //从typename可以看出,category是一个类型 return _distance(first,last,category());//显示调用category类的构造函数,返回该类的一个对象 } /*****下面的函数用于将指针移动n位的方法*/ //一般迭代器求向前移动的方法,与双向迭代器和随机反问迭代器不同 template
inline void _advance(InputIterator& i,Distance n,input_iterator_tag) { while(n--) { ++i; } } //针对双向迭代器移动的方法 template
inline void _advance(BidirectionalIterator &iter,Distance n, bidirectional_iterator_tag) { if(n>=0)//当n大于0时,向后移动 { while(n--) { ++it