Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The...

21
Topic 11 Iterators

Transcript of Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The...

Page 1: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

Topic 11

Iterators

Page 2: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

One thing at a time:

int sum(int values[], size_t length){ int total = 0;

for (size_t i = 0; i < length; i++) total += values[i];

return total;}

Iteration

9 / 28

Iteration is the process of working with a collection of things, one thing at a time. Thisis a very common thing to do with arrays...

Page 3: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

One thing at a time:

int sum(int *values, size_t length){ int total = 0;

for (size_t i = 0; i < length; i++) total += values[i];

return total;}

Iteration

10 / 28

... which, as we saw in lecture 16, is the same thing as iterating over values pointed atby a pointer.

Page 4: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

One thing at a time:

int sum(vector<int>& values){ int total = 0;

for (size_t i = 0; i < values.size(); i++) total += values[i];

return total;}

Iteration

11 / 28

We can use the same pattern when iterating over values in a vector...

Page 5: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

One thing at a time:

int sum(vector<int>& values){ int total = 0;

for (int value : values) total += value;

return total;}

Iteration

12 / 28

... or, as we saw in lecture 10, we can use C++11's range-based for loop.

Page 6: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

Not just vectors:

std::vector<int> values = { /* ... */ };for (int x : values) { /* ... */ }

Player tictactoeBoard[] = { /* ... */ };for (const Player p : tictactoeBoard) { /* ... */ }

std::list<Student> students = /* ... */;for (Student& s : students) { /* ... */ }

std::map<std::string, int> names = /* ... */;for (auto& i : names) { /* ... */ }

Iteration

13 / 28

This pattern applies to much more than just arrays and vectors, however. In fact, wewant to be able to iterate over all kinds of containers, whether they are arrays,standard library containers or objects we've designed to hold some values.

Page 7: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

Not just vectors:

Player tictactoeBoard[] = { /* ... */ };for (const Player p : tictactoeBoard) { /* ... */ }

Iteration

14 / 28

In some cases, all we need to iterate over a set of values is a pointer. If we have anarray of contiguous values (values that are next to each other in memory), we caniterate over them via pointer arithmetic.

Page 8: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

Not just vectors:

std::list<Student> students = /* ... */;for (Student& s : students) { /* ... */ }

Student

nextStudent

next

Student

next

Iteration

15 / 28

In other cases, iteration is more complicated. In a linked list (not a data structureyou're responsible for in this course, just a useful example), every element has apointer to the next element. The mechanism is more complicated, but the end result isthe same: we iterate over all of the elements in the collection.

Page 9: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

Not just vectors:

std::vector<int> values = { /* ... */ };for (int x : values) { /* ... */ }

Player tictactoeBoard[] = { /* ... */ };for (const Player p : tictactoeBoard) { /* ... */ }

std::list<Student> students = /* ... */;for (Student& s : students) { /* ... */ }

std::map<std::string, int> names = /* ... */;for (auto& i : names) { /* ... */ }

Iteration

16 / 28

Iteration, then, is something that applies to all containers. Even more, we can useC++11 range-based for loops with all containers from the standard library (as well asarrays). No matter what type of container we're using, the iteration looks basically thesame.

Page 10: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

Commonality:

one thing at a time

currently "here"

Iteration

17 / 28

What all of these different types of iterators have in common is that they allow us towork with one thing at a time and they have some internal notion of where wecurrently are in the iteration. That is, we can ask, "what's the current value?" and"have we reached the end?"

Page 11: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

Iterator:

Something that can iterate through elements andproduce references to them

"Go to the next thing"

"Give me the current thing"

"Are we done yet?"

Iteration

18 / 28

An iterator, then, is anything that can iterate through the elements of a container andproduce references to those elements. To satisfy this requirement, we need to be ableto do three things, as shown on this slide.

Go to the next thing: we need to be able to increment the iterator, moving from thecurrent element to the next one.

Give me the current thing: we need to be able to convert an iterator into a referenceto the current element.

Are we done yet: we need some way to check whether an iterator is at the end of acontainer.

Page 12: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

Iterator:

Something that can iteratethrough elements and producereferences to them

Example: pointer!

Iteration

19 / 28

Given the requirements for an iterator expressed on the previous slide, we can nowsee that one very simple form of iterator is a pointer. A pointer can be incremented(i++), dereferenced (*i) and compared with an "end" value (e.g., i == array + size).There are much more complicated iterators, where we need to instantiate objects ofiterator classes with methods that follow pointers to the next element, etc., butsometimes all we need is a pointer.

Page 13: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

Forward

Bidirectional

Random-access

Iterators

20 / 28

Page 14: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

Forward:

"Go to the next thing"

Student

nextStudent

next

Student

next

Iterators

21 / 28

A forward iterator is one that is capable of iterating in one direction only. In theexample on this slide, the iterator for a linked list can move to the next element in thelist, but there is no way to move backwards.

Once again: you are not responsible for understanding, describing or using linked listsor any other container type that isn't std::vector, but these examples are helpful forunderstanding different iterator categories.

Page 15: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

Bidirectional:

"Go to the next thing"

"Go to the previous thing"

Student

nextprevious

Student

nextprevious

Student

nextprevious

Iterators

22 / 28

A bidirectional iterator, as the name suggests, can be both increment anddecremented. We can move both forwards and backwards through the container withthis category of iterator. The example on the slide depicts a doubly-linked list, in whicheach element has a pointer to both the next element and the previous element. Thisallows the iterator to move forwards or backwards by one element.

Since a bidirectional iterator can do everything a forward iterator can do (and thensome), we can say that a bidirectional iterator is a special kind of forward iterator.

Page 16: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

Random access:

"Go to the next thing"

"Go to the previous thing"

"Go forward/backward N spaces

Iterators

23 / 28

The final category of iterator that we will discuss is the random access iterator. Arandom access iterator can move forwards or backwards, like the bidirectional iterator,but it can do it by an arbitrary number of elements in a single operation. This meansthat a random access iterator is a special kind of bidirectional iterator. Forexample, in order to increment the bidirectional iterator from the previous slide by ten,we would need to increment the iterator ten times. With a random access iterator, wecan perform a single "move ahead ten spaces" operation.

We have already seen and worked with random access iterators: a pointer is arandom access iterator. We can increment or decrement it an arbitrary number ofspaces using pointer arithmetic.

Page 17: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

Iterators in std::vector:

vector<int> numbers = /* ... */;for (int x : numbers) { /* ... */ }

// Iterator pointing at the first elementvector<int>::iterator i = numbers.begin();

// Iterator pointing just *past* the last elementvector<int>::iterator j = numbers.end();

Iterators

24 / 28

std::vector, like all standard library containers, provides two methods that returniterators: begin and end. begin, as you might expect, returns an iterator to thebeginning of the container. end returns an iterator that is just past the end of thecontainer. This is perhaps less intuitive, but it allows us to check whether we'vereached the end of a container with the simple test i == container.end().

Bonus note:

Standard library containers can have more methods that return iterators, such as rbegin/rend(which return iterators to walk through the container backwards) and const versions that returniterators with a const promise, i.e., you cannot use them to modify the container.

Page 18: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

For loop with iterators:

Replace:

for (size_t i = 0; i < values.size(); i++) useValue(values[i]);

With:

for (vector<int>::iterator i = values.begin(); i != values.end(); i++) useValue(*i);

Iterators

25 / 28

We can replace C-style iteration (start at index 0, access each element in turn until the

index is equal to the size of the array) with iterator-based iteration as shown on this

slide. One advantage of this change is that the new form of iteration will work even on

containers that don't support indexing (i.e., values[i]). One disadvantage is that the

type of our iterator variable tends to get long and, sometimes, complex.

Page 19: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

For loop with iterators:

Replace:

for (size_t i = 0; i < values.size(); i++) useValue(values[i]);

With:

for (auto i = values.begin(); i != values.end(); i++) useValue(*i);

for (int value : values) useValue(value);

Iterators

26 / 28

We can simplify this form of for loop by using a new keyword that is available to us inC++11 and up: auto. The auto keyword means, let the compiler figure out what thetype is. In the second example on this slide, the variable i will still have a type, whichwill still be vector<int>::iterator as on the previous slide, but we don't have totype it ourselves. This can be convenient, as sometimes the details of the iteratortype actually get in the way of reading the code: what other programmers reading thiscode really need to know is that i is an iterator over values, and a long type name canget in the way of seeing this. This is especially true when iterator types get verycomplicated, e.g., std::map<std::string, std::list<int>>::const_iterator.

Page 20: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

If you define:

class SomeClass

{

public:

typedef /* ... */ iterator;

iterator begin();

iterator end();

};

You can use:

for (/* ... */ value : someObject)

{

}

Range-based for loop

27 / 28

When a container provides begin and end methods, C++11 will allow us to use an evenclearer form of the for loop: the range-based for loop. In this form, we don't have tospecify anything about the iterator that we use to iterate over the container: thecompiler generates all of those low-level details for us. This works whether thecontainer is from the standard library or we wrote it. Your types can (and should)provide begin/end to allow range-based iteration.

Code example: IntArray.cpp

Page 21: Iterators - Memorial University of Newfoundlandanderson/teaching/3891/lecture/20/notes.pdf · The final category of iterator that we will discuss is the random access iterator. A

Iterators

Range-based for loops

New keyword: auto

Summary

28 / 28