Vector and list and their respective iterator anatomy 2

Source: Internet
Author: User

Iterators are the link between the container and the algorithm, which provides an abstract view of the data, so that the person writing the algorithm does not have to care about the specifics of the various data structures.

1, iterator overview

An iterator is an abstraction that points to a pointer to a sequence element. By using iterators, we can access an element in a sequence, change the value of an element in a sequence, move an iterator forward or backward, and so on.

Iterators can be classified into five categories depending on the effective execution of the operation: an input iterator, an output iterator, a forward iterator, a bidirectional iterator, and a random access iterator. The STL uses five classes to represent these five iterator categories:

which

· Input Iterator object does not allow external changes

· Output Iterator supports write operations on objects referred to by this iterator

· Forward Iterator not only supports the operation of input Iterator and output Iterator, but also moves forward in the sequence to the next element

· Bidirectional Iterator can be moved in both directions, pointing to the next element in the sequence or to the previous element in the sequence

· The Random Iterator can both move in both directions and access objects across multiple elements

650) this.width=650; "src=" Http://s4.51cto.com/wyfs02/M00/85/21/wKiom1eavSWRIkTtAABNlApVOkA997.png "title=" 0.png " alt= "Wkiom1eavswrikttaabnlapvoka997.png"/>

2, types associated with iterator operations and their extraction mechanisms

  The iterator is used to obtain information about the object being pointed to and the sequence being pointed to. As long as the iterator describing a sequence is given, the user can indirectly manipulate the object being pointed through the iterator, and can determine the number of elements in the sequence. To express this operation, the STL must be able to provide various types related to iterators.

Iterators need to use the following five types when manipulating elements:

Value_type: Represents the type of object that the iterator refers to.

Difference_type: Represents the distance between two iterators

Reference_type: Represents the reference type of the object that the iterator refers to. In short, it is the return type of operator* ()

Pointer_type: Represents the pointer type of an iterator-induced object. In short, it is the return type of operator-> ()

Iterator_category: The type identification of the five iterators presented in the Representative 1

650) this.width=650; "src=" Http://s1.51cto.com/wyfs02/M02/85/21/wKiom1eavZ2Ca1tqAADCp0TBFlk096.png "title=" 1.png " alt= "Wkiom1eavz2ca1tqaadcp0tbflk096.png"/>

3, adapter for iterators

STL provides many iterator-based adapters, such as Back_insert_iterator, Front_insert_iterator, Inser_iterator, Reverse_iterator, Istream_iterator , Ostream_iterator, Istreambuf_iterator, Ostreambuf_iterator and so on.

These adapters can be broadly categorized into three categories: Insert iterators, reverse iterators, and Io iterators.

Reverse iterator

As the name implies, a reverse iterator provides a traversal function in the opposite direction to a normal iterator. A reverse iterator is actually an adapter for a forward iterator that is implemented by invoking the action of a forward iterator, in order to be consistent with the concept of the iterator (begin points to the first element of the iterator, end points to the next position of the last element of the iterator), and is a little different from the forward iterator.

The implementation of Reverse_iterator has a iterator named current, which is a template parameter, which is a forward iterator. The forward iterator points to the first element in the sequence to the next position in the last element, in order to maintain the unity of the iterator concept, the rbegin of the reverse iterator should be the last element of the sequence, and rend should be the element that precedes the first element.

So, current always points to an element after the element that reverse_iterator refers to. This also means that * returns the value * (current-1), + + through to current--implementation. Paste the Reverse_iterator code below.

Summary: iterators effectively separate and glue the algorithms and data structures together. In fact, many of the containers in the STL are designed with their own iterators, because only it can know the layout of its own data structure and its traversal method, only by the standard declaration of the above mentioned five kinds of iterators to use the data type. Iterators are more used in the algorithm, with the support of generics and iterators, the algorithm can achieve high cohesion.



list.h#pragma once#include<iostream> #include <vector> #include <list> #include < assert.h> #include "iterator.h" using namespace std;template<class t>struct __ Listnode{t _data;__listnode<t>* _prev;__listnode<t>* _next;__listnode (Const T & x = t ()): _prev (null),  _next (null),  _data (x) {}};template<class t,class  ref,class ptr>struct __listiterator{typedef __listiterator<t, ref, ptr > Self;typedef BidirectionalIteratorTag IteratorCategory;typedef int  differencetype;typedef t valuetype;typedef ref reference;typedef ptr pointer;__ Listnode<t>* _node;__listiterator () {}__listiterator (__listnode<t>* node): _node (node) {} Reference operator* () {return _node->_data;} When you store a struct in a linked list, you need to access the struct member variable ptr& operator-> () {////return & (operator* ()); Return & (_node->_data);//list<aa>::iterator it=l.begin ();//cout<<it->_a<<endl;// compiler optimization, supposedly requires two->->}bool operator== (const self& s) {return _node == s._ node;} Bool operator!= (const self& s) {Return _node != s._node;} self& operator++ () {_node = _node->_next;return *this;} self operator++ (int) {self tmp (*this); _node = _noode->_next;return tmp;} self& operator--() {_node = _node->_prev;return *this;} self operator--(int) {self tmp (*this); _node = _node->_prev;return tmp;} Differencetype size () {return distance (Begin (),  end ());} reference operator+= (differencetype n) {while  (n--) {++*this;} Return *this;} self operator+ (differencetype n) {self tmp (*this); tmp += n;return tmp;} reference operator-= (differencetype n) {while  (n--){--*this;} Return *this;} self operator-(differencetype n) {self tmp (*this);tmp -= n;return tmp;}}; template<class t>class list{typedef __listnode<t> node; node* _head;public:typedef __listiterator<t, t&, t*> iterator;typedef  __listiterator<t,const t&,const t*> constiterator;typedef reverseiterator< constiterator> constreverseiterator;typedef reverseiterator<iterator> reverseiterator; typedef t valuetype;typedef t* pointer;typedef const t* constpointer; Typedef valuetype& reference;typedef const valuetype& constreference;typedef  int DifferenceType; List (): _head (New node) {_head->_next = _head;_head->_prev = _head;} ~list () {if  (_head == null) return;while  (1) {if  (_head == null) break;else  if  (_head->_next = _head) {delete _head;_head = null;} else{node* del = _head;_head = _head->_next;_head->_prev = null; Delete del;}}} /*void pushback (const t& x) {node* tail = _head->_prev; Node* tmp = new node (x);tmp->_next = _head;_head->_prev = tmp; Tail->_next = tmp;tmp->_prev = tail;} */void pushback (const t& x) {Insert (End (),  x);} Void pushfront (const t&x) {Insert (Begin (),  x);} Void popback () {Erase (--end ());} Void popfront () {Erase (Begin ());} Void insert (iterator pos, const t& x) {node* cur = pos._node; node* prev = cur->_prev; Node* tmp = new node (x); tmp->_next = cur;cur->_prev = tmp;prev- >_next = tmp;tmp->_prev = prev;} Iterator&nBsp Erase (Iterator pos) {assert (Pos!=end ()); node* prev = pos._node->_prev; node* next = pos._node->_next; Node* del = pos._node;prev->_next = next;next->_prev = prev;delete  del;return iterator (next);} Iterator begin () {return iterator (_head->_next);} Iterator end () {return _head;//explicit//return iterator (_head);} Reverseiterator rbegin () {Return reverseiterator (End ());} Reverseiterator rend () {Return reverseiterator (Begin ());} Constreverseiterator rbegin () Const{return constreverseiterator (End ());//explicit} Constreverseiterator rend () Const{return constreverseiterator (Begin ());//explicit}};void  Testslist () {list<int> l;l.pushback (1); L.pushback (2); L.pushback (3); L.pushback (4); L.pushback (5); List<int>::iterator iter = l.begin ();while  (Iter != l.end ()) {cout  << *iter <<  " "; ++iter;} Cout << endl;iter = l.begin ();while  (Iter != l.end ()) {List<int> ::iterator tmp = iter;++tmp;if  (*iter % 2 == 0) {l.Erase (ITER);} iter = tmp;/*if  (*iter % 2 == 0) {iter = l.erase (ITER);} Else++iter;*/}list<int>::reverseiterator it = l.rbegin ();while  (it != l. REnd ()) {cout << *it <<  " "; ++it;} Cout << endl;cout << distance (L.begin (),  l.end ()) <<endl; vector.h#pragma once#include<iostream> #include <vector> #include <list> #include < assert.h> #include "iterator.h" using namespace std;template<class t>class vector{ public:typedef t* iterator;typedef const t* constiterator;typedef  Reverseiterator<constiterator> constreverseiterator;typedef rEverseiterator<iterator> reverseiterator;typedef t valuetype;typedef t* pointer ; typedef t& reference;typedef int differencetype;protected:iterator _start;i Terator _finish;iterator _storage;void _checkcapacity () {if  (_finish == _storage) {int capacity = _storage - _start;int newcapacity = capacity *  2 + 3; t* tmp = new t[newcapacity];for  (int i = 0; i <  Capacity;++i) {//operator=tmp[i] = _start[i];//cannot be used with memcpy, involving pointer copies}delete[] _start;_start =  tmp;_finish = _start + capacity;_storage = _start + newcapacity;}} Public:vector (): _start (null), _finish (null),  _storage (null) {}vector (size_t size): _start (new t[ Size]), _finish (_start),  _storage (_start+size) {}~vector () {if  (_start) Delete[] _start;} Void pusHback (const t& x) {_checkcapacity (); *_finish = x;++_finish;} Void popback () {assert (_finish > _start);--_finish;} Iterator begin () {Return _start;} Iterator end () {return _finish;} Reverseiterator rbegin () {Return reverseiterator (End ());} Reverseiterator rend () {Return reverseiterator (Begin ());} Differencetype size () {Return _finish - _start;} Differencetype capacity () {Return _storage - _start;} Reference operator[] (Int index) {assert (Index < size ()); return _start[index];} Valuetype at (Int index) {assert (Index < size ());return _start[index];}}; Void testvector () {vector<int> v;v.pushback (1); V.pushback (2); V.pushback (3); V.PushBack (4); v. Pushback (5); Vector<int>::iterator it = v.begin ();while  (It != v.end ()) {cout < < *it <<  " "; it++;} cout << endl; Vector<int>::reverseiterator rit = v.rbegin ();while  (Rit != v.REnd ()) {cout  << *rit <<  " "; ++rit;} Cout << endl;cout << distance (V.begin (),  v.end ())  << endl ;} iterator.h#pragma once#include<iostream>using namespace std;struct  inputiteratortag {};struct outputiteratortag {};struct forwarditeratortag :  Public inputiteratortag{};struct bidirectionaliteratortag : public forwarditeratortag  {};struct randomaccessiteratortag : public bidirectionaliteratortag {};template <class iterator>struct iteratortraits{typedef typename iterator::iteratorcategory  IteratorCategory;typedef typename Iterator::ValueType         valuetype;typedef typename iterator::D ifferencetyPe   differencetype;typedef typename iterator::P ointer            Pointer;typedef typename Iterator::Reference          Reference;}; template<class t>struct iteratortraits<t*>{typedef typename  randomaccessiteratortag iteratorcategory;typedef typename t         valuetype;typedef typename int   differencetype;typedef typename  t*           pointer;typedef typename t &         Reference;}; template<class t>struct iteratortraits<const t*>{typedef typename  randomaccessiteratortag iteratorcategory;typedef typename t         valuetype;typedef typename int   differencetype;typedef typename t*            Pointer;typedef typename T&          Reference;}; Template <class inputiterator>int  __distance (inputiterator first,  Inputiterator last, inputiteratortag) {int n = 0;while  (first != last)  {++first; ++n;} Return n;} Template <class randomaccessiterator>int __distance (Randomaccessiterator first,  randomaccessiterator last,randomaccessiteratortag) {Return last - first;} Template <class inputiterator>int  distance (inputiterator first,  Inputiterator last) {return __distance (first, last, iteratortraits <inputiterator >::iteratorcategory ());} Template <class iterator>class reVerseiterator{protected:iterator _cur;typedef reverseiterator<iterator> self;typedef  typename iteratortraits<iterator>::iteratorcategoryiteratorcategory;typedef typename  iteratortraits<iterator>::D ifferencetype differencetype;typedef typename  iteratortraits<iterator>::valuetype  valuetype;typedef typename iteratortraits< Iterator>::P ointer  pointer;typedef typename iteratortraits<iterator>::reference   reference;public:reverseiterator () {}explicit reverseiterator (iterator i): _cur (i) {} Reference operator* () {iterator tmp = _cur;return * (--tmp);} When you store a struct in a linked list, you need to access the struct member variable pointer& operator-> () {////return & (operator* ()); return _ Cur.operator-> ();//list<aa>::iterator it=l.begin ();//cout<<it->_a<<endl;//compiler optimizations, Supposedly requires two->->}bool operator== (const self& s) {REturn _cur == s._cur;} Bool operator!= (const self& s) {return _cur != s._cur;} self& operator++ () {--_cur;return *this;} self operator++ (int) {self tmp (*this);--_cur;return tmp;} self& operator--() {++_cur;return *this;} self operator--(int) {self tmp (*this); ++_cur;return tmp;} self& operator+= (int n) {_cur += n;return *this;} self& operator-= (int n) {_cur -= n;return *this;} self operator+ (int n) {return self (*this+n);} self operator-(int n) {return self (*this-n);} Reference operator[] (differencetype n)  const {return * (*this + n);} Iterator need to implement operator+ (n);};/ /main.cpp#include "List.h" #include "Vector.h" Int main () {testslist (); Testvector (); System ("pause"); return 0;}


This article is from the "Small Stop" blog, please be sure to keep this source http://10541556.blog.51cto.com/10531556/1831592

Vector and list and their respective iterator anatomy 2

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.