Presentation is loading. Please wait.

Presentation is loading. Please wait.

CSE 332: C++ STL iterators What is an Iterator? An iterator must be able to do 2 main things –Point to the start of a range of elements (in a container)

Similar presentations


Presentation on theme: "CSE 332: C++ STL iterators What is an Iterator? An iterator must be able to do 2 main things –Point to the start of a range of elements (in a container)"— Presentation transcript:

1 CSE 332: C++ STL iterators What is an Iterator? An iterator must be able to do 2 main things –Point to the start of a range of elements (in a container) –Give access the current element to which it points An iterator may be able to do 2 other important things –Move to point to the next element in a range –Be tested for having run through the entire range Intent (according to Gamma et al., “Design Patterns”) –Provide a way to access elements of a container sequentially without exposing its underlying representation Iterators help provide interface polymorphism –Same interface, but different iterator implementations –Due to underlying containers’ different behaviors We’ll consider iterator interface methods above with –istream, ostream, array, linked list, bi-linked list

2 CSE 332: C++ STL iterators STL Iterator Syntax and Semantics Pointers and integers are both Gamma et al. iterators for (int * p = &A[0]; p – A < MAX; ++p) { cout << *p << endl; } Pointers (but not integers) are also STL iterators –Relies on associated types tricks we’ll cover later –Use traits based on typedef/struct/specialization The compiler can only check the syntax Iterator definition must provide good semantics –Including memory, aliasing, time complexity –Is it ok to implement p += n via a for loop? Why or why not?

3 CSE 332: C++ STL iterators Overview of STL Iterators STL iterators generalize different uses of pointers Interface between algorithms and data structures –Algorithm manipulates iterators, not containers STL iterator “value” can be in one of 3 kinds of states: –Dereferenceable (points to a valid location in a range) –Past the end (points just past last valid location in a range) –Singular (points to nothing, like a zero pointer) STL iterators may be compared for equality STL iterators may be copied and assigned Why are STL iterators designed this way?

4 CSE 332: C++ STL iterators Linear Search Example (Based on Austern) char* strchr(char* s, char c) { while (*s != ‘\0’ && *s != c) { ++s; } return s; } Not a very general solution –Only handles char (not wchar_t, uchar, etc.) –“ Range ” is up to but not including the ‘\0’ Only applies to “ zero terminated ” strings First generalization: use a proper range –Provide an integer range length (how far to count) –Provide a first and last pointer into the array char* find(char* start, char * end, char c) { while (start != end && *start != c) { ++start; } return start; }

5 CSE 332: C++ STL iterators A Closer Look at Ranges char* find(char* start, char * end, char c) { while (start != end && *start != c) { ++start; } return start; } searches all positions in the string (from start up to but not including end ) for a position with value c –A closed/open range: [start, end) A few questions about ranges to consider – At what position is ‘\0’ in “hello” ? –What is the last element in [0,1) ? Closed/open ranges help avoid off-by-one errors –The number of elements in the range [start, end) is end - start

6 CSE 332: C++ STL iterators Some Definitions Related to Ranges A valid range can be traversed safely with an iterator An empty range [p,p) is valid If [first, last) is valid and non-empty, then [first+1, last) is also valid –Proof: iterative induction on the range If [first, last) is valid –and position mid is reachable from first –and last is reachable from mid –then [first, mid) and [mid, last) are also valid If [first, mid) and [mid, last) are valid, then [first, last) is valid –Proof: divide and conquer induction on range

7 CSE 332: C++ STL iterators Back to the Linear Search Example Second generalization (we looked at this code before) template Iterator find2 (Iterator first, Iterator last, const T & value) { while (first != last && *first != value) { ++first; } return first; } With both the iterator and value types being template type parameters, the function becomes very generic –Searches any one-dimensional sequence of elements –But, this raises some important issues about the iterator type (especially about what other types are associated with it)

8 CSE 332: C++ STL iterators An Important Technique: Traits If we want to use iterators in templates, then we need to provide additional info about them –Some information is fairly basic Type for expressing distance between iterators Type obtained when an iterator is dereferenced –Some information is more subtle and advanced Whether or not an iterator can move backward, or be moved an arbitrary distance in constant time Why do we need to provide this information? –For basic info, to write code that compiles –For advanced info, to influence compiler’s matching To do this across diverse types, we need traits

9 CSE 332: C++ STL iterators Motivating Traits: Iterator’s Value Type Why are traits needed? See example to the left –Illustrates problem of writing a generic swap function template First approach –Work around the problem –Let compiler resolve the value type –Define a forwarding function –Defer implementation to an internal function –Can we improve this? // Austern, pp. 34: can’t write // template // void swap (I i1, I i2){ // T tmp = *i1; // *i1 = *i2; // *i2 = tmp; // } template void swap_impl (I i1, I i2, T t){ T tmp = *i1; *i1 = *i2; *i2 = tmp; } template void swap (I i1, I i2) { swap_impl (i1, i2, *i2); } value type

10 CSE 332: C++ STL iterators Iterator’s Value Type (continued) Second approach –Declare the value type within a class –Algorithms can then rely on that type in their concepts –A step in the right direction, anyway –What’s the limitation? // Based on Austern, pp. 34 template class MyIterator { public: typedef T value_type; //... private: T * current_; }; template void swap (I i1, I i2) { I::value_type temp; //... }

11 CSE 332: C++ STL iterators Iterator Traits Third approach: a partial solution –Type indirection –Via an iterator traits class –Why do this? –Have we made progress? // Based on Austern, pp. 35 template struct iterator_traits { typedef typename I::value_type value_type; }; template void swap (I i1, I i2) { iterator_traits ::value_type temp; //... }

12 CSE 332: C++ STL iterators Iterator Traits (continued) Fourth approach: a complete solution –Different versions of iterator_traits –Uses template specialization –C++ compiler will select the most specific match // Based on Austern, pp. 35 template struct iterator_traits { typedef typename I::value_type value_type; }; template struct iterator_traits { typedef T value_type; }; template struct iterator_traits { typedef T value_type; // a subtlety }; Why do we need this one, too?

13 CSE 332: C++ STL iterators More About Iterators Associated Types Difference Type –Type for “distance” between two iterators i1 and i2 –E.g., ptrdiff_t Reference, Value Types –For T *p, value type is T, *p normally returns T & –For const T *p, value type is const T, *p gives const T & Iterator Concept Category –Most refined concept it models –More about how this is used, when we cover STL algorithms in detail how far? units?

14 CSE 332: C++ STL iterators Iterator Concept Hierarchy Input IteratorOutput Iterator Forward Iterator Bidirectional Iterator Random Access Iterator value persists after read/write values have locations can express distance between two iterators read or write a value (one-shot) Linked-list style access ( slist ) Bi-linked-list style access ( list ) Array/buffer style access ( vector, deque ) “destructive” read at head of stream ( istream ) “transient” write to stream (ostream)

15 CSE 332: C++ STL iterators Input/Output Iterator Concepts & Models Important Input Iterator Concept Expressions *i (read value at the head of the stream) i->m (access member through iterator) ++i, i++ (move the iterator to next element in stream) Some Models of the Input Iterator Concept istream_iterator, most other STL iterators Important Output Iterator Concept Expressions X y(x), X y=x, y = x (copy construct / assign iterators) *x = t, (write value t into the stream) x++, ++x (move the iterator to next element in stream) Some Models of Output Iterator Concept front_insert_iterator back_insert_iterator ostream_iterator

16 CSE 332: C++ STL iterators Forward/Bidirectional Iterator Concepts & Models Important Forward Iterator Concept Expressions –Can pass same forward iterator in multiple arguments X x, X(),(default construction) ++i, i++ (move from location to location) *i (non-destructive access to container element) Some Models of the Forward Iterator Concept slist ::const_iterator hash_set ::iterator Bidireational Iterator Concept also requires --i, i-- (move from location back to earlier location) Some Models of the Bidirectional Iterator Concept list ::iterator, set ::iterator

17 CSE 332: C++ STL iterators Random Access Iterator Concepts & Models Important Random Access Iterator Concept Expressions i+=n, i-=n (moving iterator given distance in constant time) i+n, n+i, i-n, n-i, i-j, i<j (iterator arithmetic) i[n], i[n]=t (indexing a container using an iterator) –Thought Question: we can express the distance between two Forward Iterators, so why don’t those iterators have i-j or i<j ? Some Models of the Random Access Iterator Concept vector ::iterator deque ::iterator char * Compiler must be able to determine to which category an iterator belongs –Allows it to match an iterator with

18 CSE 332: C++ STL iterators Advice for Designing Your Own Iterators Use the iterator concept requirements as a checklist –Also good advice for writing containers and functors Make you support both constant and mutable objects Define associated types appropriately –More on this in the lecture on generic programming Provide as wide an iterator interface as possible without loss of efficiency Obey the aliasing rule we talked about with pointers –Two iterators equal if and only if they point to same variable i == j &(*i) == &(*j) *i == *j

19 CSE 332: C++ STL iterators Advice for Using Iterators Write a concept expression checklist for iterator developers to use in designing their iterators Watch out for empty ranges Require as narrow an iterator interface as possible without loss of efficiency –Avoid over-constraining unnecessarily –E.g., requiring just == and and != Use selective dispatching techniques to provide both efficiency and generality

20 CSE 332: C++ STL iterators Example of Using Iterators in the STL From Austern, pp. 355 Copies values from an istream into a vector What exactly is going on here? int main () { vector V; copy (istream_iterator (cin), istream_iterator (), back_inserter (V)); } (Thanks to Morgan Deters for this example)

21 CSE 332: C++ STL iterators How the Iterator Works in this Example From the g++ 2.95.2 STL source code : template class istream_iterator {... public: istream_iterator() : _M_stream(&cin), _M_end_marker(false) {} istream_iterator(istream& __s) : _M_stream(&__s) { _M_read(); }... };

22 CSE 332: C++ STL iterators For Next Time Topic: C++ STL Algorithms Assigned Reading –pages 930-933 pages 1102-1128


Download ppt "CSE 332: C++ STL iterators What is an Iterator? An iterator must be able to do 2 main things –Point to the start of a range of elements (in a container)"

Similar presentations


Ads by Google