I want to begin our discussion of iterators by looking at the way that iterators are used in the standard
library so we're going to take a look at how to traverse a simple vector.
So I'm going to make it a vector of strings let's call it names.
And here I'll just add a couple of names so let's have John let's have Jane Jill Jack.
There we go.
OK.
So now what I want to do is I want to go through every single one of those names and iterators are the
mechanism that actually helped me do that.
So the first thing I want to do is I want to get an iterator which points to the beginning of this container.
So the way this is done is I make a vector of string iterator called it and I'm going to get that iterator
to point to the first element.
And this is done using names don't begin.
So names that begin gives us an iterator which points to the first element and it exists both as a member
function of the vector.
And it also exists as a global function as well which is which basically means you can write begin of
names like so.
So it's really up to you how you go with this.
The upside of the global approach is that it also works for arrays for example and of course arrays
don't have any member function so this is the only way you can get the start of an array.
So having set this up what we can do with the iterator is first of all we can actually follow the iterator.
Now you can think of an iterator as you think of a pointer or something which accepts the dereferencing
operator as something which allows you to perform arithmetic on it.
So if you want to print out the first name which is John we would simply say something like the following
would say first name is and then start it and line.
So we are essentially dereferencing the iterator We're following the operator to see where it actually
points to.
So let's execute this just to see that it works.
OK so we get.
First name is John.
Now if you want to get the next tell them what we can do is we can increment the iterator so we can
do plus plus it and you can also do a postfix plus plus if you want to.
So it's very much like a pointer it suddenly feels like a pointer even though behind the scenes it doesn't
have to be and a vector iterator for example is unlikely to be compatible with an ordinary string pointer.
In this case.
Now the interesting thing about the iterator with now moved it to point to Jane but this iterate that
doesn't just allow you to get the elements you can also use the iterator to modify the element So for
example I can do its append.
And notice I'm using the arrow here because essentially I am following these race to get the underlying
elements and I can append to that element so I have change and I can append Gudel for example.
There we go.
So this I've now modified an element inside the vector itself and I can print it out.
So the second name is Star It's again.
Let's execute this once again.
All right so now we get second name is Jane Goodall.
Now what about all the other elements.
How can we print them all out until the end of the actual vector.
Well we can do a WHILE loop where we keep iterating the iterator that we have.
We keep incrementing it effectively and we check that it's not equal to name start and now it's important
to realize what names though.
And gives us.
It does not give us an iterator which points to the last element.
What it does instead is it gives us any iterator which points to one after the last.
So if you have a sequence of values 1 2 3 and 4 then the invocation of and of would actually point you
here it would point you to a memory location that's after the last element.
So this is where it would point to and that is obviously the point where you would stop these orating
because you are not interested in this particular location you are interested in all the locations before
names and but you're not interested in names and itself.
And once again it exists both as a member function as well as a global function.
So let's print out the rest of the names.
I'm going to say another name.
And once again the reference either age nature to have that thing printed let's execute this.
And let's see what we get.
All right so we're now getting all the foreign names so first name is John second name is Jane Goodall
and now we have two other names Joe and Jack.
So this is great.
Now we might also want to traverse the sequence in reverse order.
Now obviously not all containers are going to allow you to go through them in reverse order.
For example if you have a singly linked list you can't really go in reverse order because you don't
have the pointer to the previous element but in the case of a vector It's rather easy.
So let's take a look at how we would do that.
So I'm going to make a for loop where I'll make a variable called our high.
And notice I'm going to start using auto and you could have used auto in here for example so instead
of having vector off a string iterator you would just say auto It's a lot easier to do this way.
So for auto are equal to our begin all names.
So our begin is the begin equivalent but it's for reverse iteration.
So if you think of a sequence of numbers let's say 1 2 and 3.
And if you think about where our big end points to begin with points to the last element.
So whenever you want the last element of some sequence you just call our begin on that.
And then you can sort of dereference that so this is our begin and then our and would actually point
here.
So our end would point to the element immediately before the first elements.
Once again very useful as a terminating condition so we're going to go through the iterator starting
at our begin.
We want our right to not be equal to our end of names.
And once again we're using plus plus our eye.
Now you might be wondering Well hold on if we're going backwards.
Why is that plus plus.
But in actual fact what C++ does with iterators.
It assumes that plus plus represents the idea of advancement.
So if you have a reverse iterator it's still advancing it's just advancing in reverse order.
So we use plus plus to advance the iterator and minus minus to roll back the iterator.
And so even though we're going backwards it's still a plus plus if you want to iterate in the backwards
order.
So let's suppose here that we want to print out each of the elements comma separated but we don't want
the comma after the last element that we print.
So how do we do this.
What we can.
First of all printout of the Hellman's itself seek out star R.I. and then we can check whether or not
we are at the last element and once again here just like with pointers I can use an iterator and perform
arithmetic on it so I can see if all right plus 1 is not equal to r and all names then please print
a comma.
So what's happening here is I'm taking the iterator I'm adding one to it which means I'm advancing the
iterator by one step.
So if I were if I had an iterator pointing to this element for example and I added 1 to it I would be
pointing to this element because it's a reverse iterator so I'm checking whether or not I've reached
the end.
And if I haven't then I'm putting a coal mine here and then at the end of it all let's also put an end
line.
So let's execute this let's see what we get from this.
OK so as you can see we can get a printout of all the four names.
Here we have Jack Jill Jane Goodall and John so they're printed in reverse order this time round.
Now notice when we use the iterator here to modify the underlying element the reason we were able to
do this is because it wasn't a constant iterator but there are also constant iterators.
If you want to use them and indeed there are constant reverse iterators as well.
So for example I can get a constant reverse iterator to the reverse begin or the ending of the names
collection.
So I can say that offspring cost reverse iterator called.
Well it's called Jack because that's what it is going to point to and I can say See begin of names now.
One thing I cannot do is I cannot modify the underlying data storage elements so here if I wanted to
append something to jack I couldn't just say Jack plus equals string creature for example.
This is not valid because the iterator is a constant iterator and it's not going to allow me to actually
modify the collection.
Finally the one thing that I wanted to mention which is a simplification of modern C++ is the range
based for loop.
And this is the for loop where you can say auto name in names and you can print out a name like so.
So this is the latest and freshest approach to how you can actually iterate sequences if you want to
go through every single element.
Now this only goes in the forward order.
There is no reverse for range Lou.
But essentially what's happening here is as follows.
So right here on the right hand side you have to have a variable of a type which implements begin and
end.
So you need begin and to be implemented.
But if they are implemented what's happening is you have this variable here you have this variable and
it's being assigned the value of star.
It's so you're iterating the sequence of names in this case using begin and end.
You are getting an iterator called it your DVR syncing that iterator so you're following that iterator
to the underlying data and then you're assigning it to a variable which is defined here and this variable.
It can be a value like so in which case you would typically have a full copy of the memory.
Not very efficient.
Or you can have it as a reference or if you are using some outdated vector of Boolean or something you
might even have an r value reference like this.
But in most cases actually this approach the one with the two ampersands is the safest approach to go
for and I recommend if you write ordinary range based for loops I recommend you do it like this.
99 percent of the time just for the sake of safety.
So this is how you would iterate a collection which implements begin and end functions and it's very
convenient and very easy to actually print something out.
So let's execute this.
And let's see what we've got here.
All right so as you can see we have name equals John-James Goodo Chu and Jack.
So that's the printout from our so-called arr. based for loop so this has been a small overview of some
of the iterators in the standard library.
Suddenly the most commonly used ones.
And this idea of implementing begin and end is something that we are going to be doing ourselves in
the subsequent lessons.