Directory
- Use of iterators
- Types of iterators
- Invalidation of Iterators
- Implementation of Iterators
1. Use of iterators
In order to improve the efficiency of C + + programming, many containers are provided in STL, including vector, list, map, set and so on. Some containers, such as vectors, can access the data inside the container by means of a foot index, but most containers cannot use this method, such as list, map, set. Each container in the STL is implemented with an embedded iterator class, and different containers have their own iterators that use iterators to access the data in the container. In addition, with iterators, you can combine containers with general-purpose algorithms so that you can perform the same operations on different containers, such as the Find Lookup function, by giving different iterators to the algorithm. Iterators have overloaded the pointers with some basic operations, such as *,, + +, = =,! =, =, which have the ability to traverse complex data structures, and the traversal mechanism depends on the structure of the traversal, and the use of all iterations is very similar to the use of pointers. The container's head and tail iterators are obtained through the Begin,end function, and the end iterator is not contained within the container, which indicates that the container is empty when begin and end return the same iterator.
Template<typename Inputiterator, TypeName t>const T &value) { while (First! = Last && *frist! = value) + + first; return First ;}
#include <iostream>#include<vector>#include<list>#include<algorithm>using namespacestd;intMainintargcConst Char*argv[]) { intarr[5] = {1,2,3,4,5}; Vector<int> IVec (arr, arr +5);//Defining container vectorslist<int> iList (arr, arr +5);//Defining a container list//look for the number of Ivec between the head and tail of the container 3vector<int>::iterator iter1 = Find (Ivec.begin (), Ivec.end (),3); if(Iter1 = =ivec.end ()) cout<<"3 not found"<<Endl; Elsecout<<"3 found"<<Endl; //finding the number of shaping between the head and tail of the container IList 4list<int>::iterator iter2 = Find (Ilist.begin (), Ilist.end (),4); if(Iter2 = =ilist.end ()) cout<<"4 not found"<<Endl; Elsecout<<"4 found"<<Endl; return 0;}2. Types of iterators
Iterators can be divided into 5 classes based on the operations supported by Iterators.
1) Input iterator: is a read-only iterator that can be read only once at each traversed location. For example, the find function parameter above is an input iterator.
2) Output iterator: is a write-only iterator that can only be written once at each traversed position.
3) Forward iterators: the ability to combine input and output iterators, but it can read and write the same position repeatedly. But it does not support operator--, so it can only move forward.
4) Bidirectional iterator: Much like a forward iterator, it's just as easy to move backwards and forward.
5) Random access iterators: All functions with bidirectional iterators. Moreover, it provides "iterator arithmetic", that is, in one step can jump forward or backward anywhere, including all operations of the pointer, can be random access, arbitrarily move the specified number of steps. Supports all the operations of the previous four iterator, and additionally supports operations such as it + N, it-n, it + = n, it-= N, It1-it2, and It[n].
STL Each container type defines const_iterator, which can read only the values of the container, and cannot modify the values of the elements that are pointed to within the container. Vector, String, deque random access iterators, List, Set, map, Mutiset, Multimap bidirectional iterators .
3. Iterator invalidation
the insert and erase operations of the container may cause the iterator to fail , and for the erase operation, do not use the iterator that precedes the operation, because the erase iterator must be invalidated, and the correct approach is to return the iterator at the time of the delete operation.
#include <vector>using namespacestd;intMainintargcConst Char*argv[]) { intarr[5] = {1,2,3,4,5 }; Vector<int> IVec (arr, arr +5);//Defining container vectors//iterator invalidation//for (Vector<int>::iterator it = Ivec.begin (); It! = Ivec.end ();) {//Ivec.erase (it);/}//returns the iterator after the erase operation for(vector<int>::iterator it = Ivec.begin (); it! =ivec.end ();) { it = ivec.erase (it); } return 0;}4. Implementation of Iterators
Each container in the STL has its own iterator, the interfaces of various iterators are the same, the internal implementation is not the same, which also directly embodies the concept of generic programming, the following in the single-linked list class embedded a iterator class to achieve the iteration of the single-linked list
1#include <iostream>2 3Template<typename t>4 structListNode {5 T value;6listnode*Next;7 ListNode () {8Next =0;9 }TenListNode (T val, ListNode *p =nullptr): One value (val), next (p) { A } - }; - theTemplate<typename t> - classList { - Private: -Listnode<t> *M_phead; +Listnode<t> *M_ptail; - intm_nsize; + Public: A List () { atM_phead =nullptr; -M_ptail =nullptr; -M_nsize =0; - } - //inserting elements from the tail of a list - voidpush_back (T value) { in if(M_phead = =nullptr) { -M_phead =NewListnode<t>(value); toM_ptail =M_phead; +}Else { -M_ptail->next =NewListnode<t>(value); theM_ptail = m_ptail->Next; * } $ Panax Notoginseng } - the //print linked list elements + voidPrint (Std::ostream &os = std::cout)Const { A for(listnode<t> *ptr = M_phead; ptr! = M_ptail->next; ptr = ptr->next) theStd::cout << Ptr->value <<" "; +OS <<Std::endl; - } $ $ //built-in iterators - classIterator { - Private: theListnode<t> *m_ptr; - Public:WuyiIterator (listnode<t>* p =nullptr): the m_ptr (p) { - } Wu -Toperator*()Const { About returnM_ptr->value; $ } -listnode<t>*operator()Const { - returnm_ptr; - } Aiterator&operator++() { +M_ptr = m_ptr->Next; the return* This; - } $Iteratoroperator++(int) { thelistnode<t>* tmp =m_ptr; theM_ptr = m_ptr->Next; the returniterator (TMP); the } - in BOOL operator==(ConstIterator &arg)Const { the returnArg.m_ptr = = This-m_ptr; the } About the BOOL operator!=(ConstIterator &arg)Const { the returnArg.m_ptr! = This-m_ptr; the } + - }; the Bayi //returns the list head pointer theIterator Begin ()Const { the returniterator (m_phead); - } - the //returns the tail of the linked list pointer theIterator End ()Const { the returnIterator (m_ptail->next); the } - the //other member functions the the };94 the intMain () { thelist<int>l; theL.push_back (1);98L.push_back (2); About l.print (); - for(list<int>::iterator it = L.begin (); It! = L.end (); ++it) {101Std::cout << *it <<" ";102 }103Std::cout <<Std::endl;104 return 0; the}
Reference: http://blog.csdn.net/shudou/article/details/11099931
C + + iterator principle, invalidation, and implementation