ITERATORS Iterator • An iterator in C++ is a concept that refines the iterator design pattern into a specific set of behaviors that work well with the C++ standard library. • The standard library uses iterators to expose elements in a range, in a consistent, familiar way. • Anything that implements this set of behaviors is called an iterator. • Allows Generic Algorithms • Easy to implement your own iterators and have them integrate smoothly with the standard library. Iterator Pattern • The iterator pattern describes a set of requirements that allows a consumer of some data structure to access elements in it with a familiar interface, regardless of the internal details of the data structure. • The C++ standard library containers (data structures) supply iterator interfaces, which makes them convenient to use and interoperable with the standard algorithms. • The iterator pattern defines a handful of simple requirements. An iterator should allow its consumers to: • • • • Move to the beginning of the range of elements Advance to the next element Return the value referred to, often called the referent Interrogate it to see if it is at the end of the range Iterators in C++ • The C++ standard library provides iterators for the standard containers (for example, list, vector, deque, and so on) and a few other noncontainer classes. You can use an iterator to print the contents of, for example, a vector like this: vector<int> v; // fill up v with data... for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) { cout << *it << endl; } C++ Iterators • C++ iterators permit the same operations as the iterator pattern requires, but not literally. • It's all there: move to the beginning, advance to the next element, get the referent, and test to see if you're at the end. • In addition, different categories of iterators support additional operations, such as moving backward with the decrement operators (--it or it--), or advancing forward or backward by a specified number of elements. Iterator Types • 5 main types of Iterators in C++ • • • • • Read only Write only Forward Iterator Reverse or Backwards Iterator Random Access Iterator • With exception of Read and Write, as we go down every iterator is a superset of the previous one in terms of functionality. • Common e.g. -> Pointers are a type of random access iterators. Forward Iterators • Essentially only need to traverse over elements • However to make STL – compliant, or to be able to interface with STL Algorithms, an iterator over a datastructure needs to implement the following functionality • Required Functionality (Forward Iterator) • Assignment • Tests for Equality • Forward advancement using the prefix and postfix forms of the ++ operator • dereferencing that returns an rvalue (value) or an lvalue (address) Case Study – Singly Linked Chainlist • • #include <iterator> #include <iostream> • using namespace std; • • • • • • • • • • • • • template <class T> class linearList { public: virtual ~linearList() {}; virtual bool empty() const = 0; virtual int size() const = 0; virtual T& get(int theIndex) const = 0; virtual int indexOf(const T& theElement)const = 0; virtual void erase(int theIndex) = 0; virtual void insert(int theIndex,const T& theElement) = 0; //virtual void output(ostream& out) const = 0; }; • • • • • • • • template <class T> struct chainNode { // data members T element; chainNode<T>* next; // constructors come here }; Chainlist class • • • • • • • • • • • • • • • • • • • • • • • template <class T> class chain : public linearList<T> { public: //constructors & destructors chain(int); ~chain(); T& get(int theIndex) const; int indexOf(const T& theElement) const; void erase(int theIndex); void insert(int theIndex,const T& theElement); void traverse(); bool empty() const {return listSize==0;} int size() const {return listSize;} protected: bool checkIndex(int theIndex) const; chainNode<T>* firstNode; int listSize; }; Iterator Class • • • • • • • • • • • • • • • • • • • • • • • • //Iterator Class class Iterator : public std::iterator<std::forward_iterator_tag, T> { private: chainNode<T>* Node; public: Iterator(chainNode<T>* p){Node = p;} ~Iterator() {} // The assignment and logical operators Iterator& operator=(const Iterator& other) { Node = other.Node; return(*this); } bool operator==(const Iterator& other) { return(Node == other.Node); } bool operator!=(const Iterator& other) { return(Node != other.Node); } //For STL-Tagging Reasons - ignore Iterator Class - continued • • • • • • • • • • • • • • • Iterator& operator++() { if (Node != NULL) { Node = Node->next; } return(*this); } • • • • • • // Return a reference to the value in the node. Do this instead // of returning by value so node can be updated directly T& operator*() { return(Node->element); } • • • • • • // Return the address of the value referred to. T* operator->() { return(&*(chain<T>::Iterator)*this); } Iterator& operator++(int) { Iterator tmp(*this); ++(*this); return(tmp); } }; New members for Chainlist • Iterator begin() { • return(Iterator(firstNode)); • } • • • Iterator end() { return(Iterator(NULL)); } • Aaaaaaand We are DONE!!! • Remember: Iterator class is public member of Chainlist class. Usage Case: Traverse function • • • • • • template<class T> void chain<T>::traverse() { for (chain<T>::Iterator it = begin();it != end(); ++it) { cout<<*it<<endl; } } • NOTICE the standard FOR LOOP ITERATION METHOD • Power of Iterators: Same method for traversing REGARDLESS of underlying data structure!!!! References • Wikipedia • What is an iterator in C++ part 1 by Oreillynet.com • UF CISE COP3530 Class Slides