In this video, I'd like to go over some live examples of how to use iterators.
There'll be a bunch of examples here, and I'll go through them 1 at a time
so that you can really understand what's going on.
I'm in the section 20 workspace in the iterators project.
And first things first. You'll notice that I'm including
a bunch of header files here:
vector, set, map and list. These are all containers in the stl.
We haven't really talked about set, map and list too much,
but that's the whole point. We really don't need to know that much about them
to be able to iterate through them.
We'll talk about them in detail in future videos.
So the first thing we'll do is we'll have a couple of functions, and
here's a function that we're going to use, and we're not going to use it too much.
But if we ever need to display
a vector of integers, we're going to call this function, it's just going to display it a nice little format.
Okay. So I'm going to close that up, and that way you know what it is.
So here's my first function.
And what I did was I broke this up into I think 5 different functions.
That way it's all more self-contained rather than having 1 just huge main with all the
examples in it.
So in this case, let's walk through this.
We're creating a vector right here of integers called nums1.
And we're putting 1 2 3 4 and 5 into that vector.
So this is where we're at right now 1 2 3 4 and 5.
And remember, the end of the vector is after the last element.
So we want to create an iterator now, and that's what I'm doing right here.
I'm using it, and notice I'm using auto. I'm letting the compiler reduce
the type of the iterator.
Obviously, it's going to be an iterator that iterates over vectors of integers,
right. That's the idea here. So I'm going to call nums1.begin.
That's going to give me the iterator to that first element
and assign it to it. So "it" is here,
and it's going to be pointing there. Now remember, this is not a real pointer.
This is an object okay, but the syntax
and the way it feels is very pointer like, and that's by design.
So that's pointing to the 1. In order to get to the 1,
I need to dereference that iterator right there.
And what that's going to do is it's going to give me the 1, the - the object in the container.
And in this case, I'm going to display it. Okay. So it's as simple as that.
Now what I want to do is move this iterator.
So I'm incrementing the iterator right here, and I'm incrementing it by 1.
So what's going to happen, the iterator now will be pointing to 2.
What do we do? We're displaying it again, so I'm going to display a 2.
Now you'll notice what's happening in the next line I'm saying
iterator plus equals 2. So I'm incrementing the iterator by 2.
It was at 2. So I'm going to go 1 2. Now it's going to be
pointing to the element number 4.
What do I do? Display it.
Now I'm going to move it right back down by 2. So I'm going to move it back to the 2
and display that.
And then the last thing I'll do is I'll set the iterator to point to the element
that's not at the end. Remember, there is no element at.The end the end just means you're at the end of the list.
But I want to go 1 back from it,
so I really want to point to the end of the list the 5 in this case.
So what we're doing is, in this case, we're going over here and then we're backing up 1,
so that.
So if I run this this test function right here,
that should be the output 1 2 4 2 5.
And what's interesting here is,
you can see how these iterators feel just like pointers, right.
And that's real handy.
I'm using the auto here. It saves a lot of -- makes it a lot easier to read.
I'll use it in some places. I won't use it in others that way you can actually see both styles.
So that's it. If I run this program now,
let me go down to my main and make sure that I'm calling test 1,
I am right there. So if I run this now, what I've got is
I should get 1 2 4 2 5, exactly like we thought.
So that's test 1. So let me collapse this guy, and we'll move on to test 2,
and I'll go down to my main, and I'll just make sure that i comment out test 1
and uncomment out test 2. Perfect.
So now let's take a look at test 2 and see what's going on in there.
So here's test 2.
We're doing the same thing we're creating a vector of integers and initializing it
from 1 to 5, so we've got 1 2 3 4 5
and here is the end right here.
I'm creating another iterator. I'm calling it it again.
This way this time I'm doing it long style I'm not using auto.
And you can see it's really pretty straightforward. It's just a lot of extra typing.
So we're creating a stud vector of integers and that's the iterator,
and we're calling it "it".
And we're initializing it nums1.begin which is the first
element in this vector which is that 1 right there.
So that's where we're at now.
And now you can see what's happening here I've got a while loop.
It's really simple. I'm saying while the iterator
is not pointing to this guy over here the end.
In other words, while the iterator is in the real list in the container,
in this case, a vector.
What I want to do is display what it's pointing to and then increment.
So you can see what this is doing. It's just going here and then here and then here and then here
and then it's going to stop. So this will print out 1 2 3 4 and 5,
right, just like that.
So let's take a look at this loop right here.
What we're doing here it's really the same thing. Now remember, this iterator now, "it" is over here.
It's pointing to the end. So if I want to go back to the beginning,
I could just simply say it equals numbs1.begin,
rightSo I'm resetting that iterator to point to the beginning of this container of this vector.
So what I'm doing is the same loop while I'm not at the end of the list.
This time I'm doing this right here. Now that's an interesting statement.
Remember, it's dereference the iterator equals 0,
just like we did with pointers.
What are we doing, we're storing 0 where the iterator is pointing,
and we're looping through. So what we're doing is we're doing this.
We're changing all of those values in that vector to 0,
and then I'm just calling display numbers which should display a bunch of 0s.
All right. So let me erase this and give this a run and see what we get.
There's our output 1 2 3 4 5,
just like we expected and then a bunch of 0s when we call the display function.
Hopefully, you all are with me. These iterators are pretty straightforward,
but it's important to understand them because we really need to use them with the
algorithms.
So we have to be able to make sure that what we're getting is what we want.
So let's take a look at test 3. Let me take care of main real quick,
and I'll uncomment this one out so we can run test 3.
And here's test 3. Now what we're going to do here is we're going to use a constant iterator.
All a constant iterator is is an iterator but I can't
change what it's pointing to. It's constant.
So we could do this a couple of different ways. We're doing the same
declaration here of num1s that's my vector of integers, again
1 2 3 4 5.
Now what I'm doing here is I'm saying it1
is a const iterator,
notice const_iterator.
What that's doing is it's creating a constant iterator not just an iterator,
again a constant iterator
and it's starting at the 1 again, num1 to begin.
And I'm not going to write that again because you guys kind of know what's going on.
Now if I wanted to not use this long style and just use the auto,
I can't just say auto it1 equals nums1.begin
because that'll give me a regular iterator. I have to say cbegin
that's going to give me the constant iterator.
So these 2 lines would be equivalent.
Okay. We could do it either way.
Now what we're doing here is we're just looping through and printing all out again 1 through 5.
But let's see if we can change things, right. Remember, here
we're trying to change each one of those elements to 0 just like
we did in test 2 a little while ago. I can't do that.
I'm not allowed to do that because it's a const iterator right here.
So if I try to do that,
let me uncomment that line out right here,
if I try to do that, I should get a compiler error,
and it's exactly right. Now this is one of the things that you'll notice about
compiler errors for the standard template library.
They're not exactly readable compiler errors. Some of them are really really nasty and hard to understand,
but this 1's not too bad. It says error assignment of read only location.
That gives you a clue, right. I mean we've got a constant iterator here.
You're trying to write through it.
So that's the rest of the error message, which is kind of nasty to read.
So I'll comment this back out. And if I run it now,
I should just get the 1 through the 5, just like we did before. Perfect.
Now let's take a look at test 4, which adds a few more little things to the mix.
We'll use some containers that we haven't used yet.
So let me uncomment test 4,
and let's take a look at test 4. There's a lot going on here.
First thing is we're going to use a reverse iterator first.
So what we're doing here,
we've got a vector 1 2 3 4, I probably should have put the 5 in there, I forgot,
so but it doesn't matter. We've got a vector 1 2 3 4, and it's vec. It's a vector of integers.
Now I'm creating it1 as my iterator.
And notice that I'm using auto,
and I'm using rbegin right there. That's a reverse iterator.
That's what the r stands for. And then what I'm doing is
while it1 is not equal to vec.rend.
So now we're just going the other way around, right. So we're going 4 3 2 1
and the end is actually over here now,
and we're simply displaying and notice I'm incrementing,
right. You may want to decrement since you're going the other way,
but we're using a reverse iterator.
So incrementing here really means decrementing here
and the other way around as well. Now let's look at a couple more examples.
Here what we've got is a container we haven't used yet.
We'll use it a lot later on. We'll actually do a nice little challenge with it. It's a list.
A list is basically a doubly linked list. So
remember how a vector was a bunch of data contiguous in memory.
Well, a list is some items that kind of look like that or elements.
And then we've got pointers back and forth
so that we can move from one to the next one really easily.
So that's all it is. We don't really have to worry too much about how it's implemented
behind the scenes to use it which is really cool.
So look what I'm doing here, I'm declaring name,
actually I should call that names, but that's okay. Name
is a list of strings.
And I'm initializing it to Larry Moe and Curly.
Now what I'm doing is I'm setting it2, and this would be Larry here, this would be Moe here,
and this would be Curly over here.
Then I'm saying it2
is a constant reverse iterator. That's the cr.
So right now, it2 is pointing right over here at the end
because it's a reverse iterator.
If i dereference it, it's going to print out Curly.
Now I'm going to increment it which simply means move it over here.
Remember, incrementing means going reverse.
So in this case, I'm coming over here,
and I'm pointing to Moe. And right here I'm going to display Moe.
Over here, I displayed Curly.
So that takes care of that one. And then let's do a few more.
Now this is a data structure that we haven't used yet, a container we haven't used.
It's a map. What is a map. A map is --
think of a map as a key
and a value.
So it's a pair.
And I talked about this earlier. There's a class called std pair,
and that's basically what's happening. The first item in there is called first,
and the second item in the pair is called second,
and we can access them directly. So look what I'm doing here, I'm creating
favorites.
And favorites is a map of string, string pairs.
And I'm just initializing them.
So all we're doing here is creating an association between 2 strings.
So Frank likes c++. Bill likes Java. James likes Haskell.
Or Frank hates c++. Bill hates Java,whatever makes sense here.
So that's the map.
And now what we're going to do we're going to have another iterator, in this case, it3,
and it's favorites.begin. So it's going to go to the first item
in that map, which, in this case, is Frank.
And I'm going to loop while it3 while that iterator is not
pointing to the end of that map.
Now how is a map stored behind the scenes?
It's a complex data structure. It doesn't matter.
I don't need to know that to use this kind of logic.
That's the beauty of this. I don't -- really doesn't matter what how it's implemented behind the scenes.
So in this case, while I haven't hit the end of that map,
for each one of those guys, I'm going to take
it3 first and it3 second,.
Makes sense, right? So we're basically using the arrow operator
dereferencing the iterator,
getting to that pair and then taking the first item and the second item in the pair
and then we're incrementing the iterator.
So let's run this.
And here are results. Let me scroll up just a little bit here.
Here we're displaying this reverse iterator.
We're using the reverse iterator to display this vector vec, and we're getting 4 3 2 1.
Over here, we got Curly and Moe. Remember, we're starting at the back. So we're getting Curly, and then
we're incrementing, which means moves to the left, and I've got Moe.
And then I'm just iterating over this map. So I'm getting Bill
Java, Frank c++,
James Haskell. Now notice the order here.
It's not the order I put them in. The last one we'll do is we'll do test 5.
And test 5 is pretty easy. So far everything we've done,
we've iterated through an entire container.
What we're going to do here we're just going to iterate over a subset of the container.
So we have a vector of integers, again
1 2 3 4 5 6 7 8 9 and 10.
And here's the end.
And now I've got 2 iterators.
I'm using auto for both so the compiler can figure out the type.
And I'm saying start that's the name of my iterator
is equal to vec.begin plus 2.
Well vec.begin as this guy, plus 2 would be
the 3.
And finish
vec.end minus 3. Well, here's vec.end minus 1 2 3.
That's what we've got. That's start and finish.
So now what I want to do is I just want to display the elements between them. So right there is the logic
while start is not equal to finish.
Display what start is pointing to. So it's going to display 3
and then increment start, display 4, display 5, display 6, display 7.
Now they are equal. So this fails, and we're done. So this will display
this subset of that vector.
All right. So let's run this.
And you can see 3 4 5 6 and 7 being displayed right here.
Okay. So play with these examples.
I've broken them up into these small test cases
that way you know tweak them a little bit rather than having one huge main
that's going to get really complicated. So come in here, comment them out,
add your own logic, play around with reverse iterators,
constant iterators, regular iterators.
You saw how I created the map so you can kind of figure out
based on my code what I did. Obviously, I'm going to talk about
lists and forward lists and maps and vectors and
sets and everything else in the upcoming videos.