.
Hi,
I just remembered a doubt I’ve had from before. Does it matter if you call a function in the loop’s condition or use a variable? For example:
VS
In this case, does it make a difference if we call li.End() directly or store it in a variable and then use it? Because in my mind, I think that if I store it as a variable, it will just call the function once and then simply use the variable’s value for subsequent condition evaluations (which should be faster) but if I don’t store it in a variable, it’s gonna keep calling the function every time the loop has to evaluate the condition.
Thanks a lot!
It’s fine to call a function from a loop condition. In the case of a function like an iterator’s end() function, the compiler will probably optimize away the function call anyway.
Got it, thanks.
Hi, I was once asked a question in an interview "what is the difference/similarity between an iterator and a pointer"…I replied "a pointer is an iterator because it can be used to traverse a list/array"..However, can you please help/elaborate in answering this question? Thank you!
A pointer is simply a variable that holds an address. An iterator is an object that is used to traverse a container. Iterators are generally implemented using pointers. So they’re related, in that one can be implemented using the other, but iterators are more for a specific purpose whereas pointers are more general.
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n;
vector<int> v;
cin>>n;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
v.push_back(x);
}
for(vector<int>::iterator it=v.end();it!=v.begin();it-)
{
cout<<*it<<" ";
}
}
output:"garbage" 5 4 3 2 instead of 5 4 3 2 1
why?
end() is one past the end of the vector.
If you want to walk through the vector in reverse, you should iterate from rbegin() to rend() and use operator++.
Is this a good place to use the keyword "auto"? For example:
Yes, it’s the perfect place for using the auto keyword in this fashion.
Hey Alex, so I’m sort of confused about Iterators. I know what they are and how to use them. But when you use ::iterator, what does that mean? Are you accessing a static object called iterator that is in every container class? or is iterator a separate class that is being used by the container class (like association)?
Another thing I was confused about is when you use it->first and it->second. So does that mean first and second are public members variables of std::pair? Also, I did my maps in a different way than yours, is there anything wrong with it? I used a for loop instead of a while for everything and try_emplace instead of insert for maps, is that okay?
Iterators in the standard library are generally implemented as nested classes, therefore, when you see something like std::vector::iterator, we’re accessing the iterator class that’s nested inside of std::vector. This isn’t a static object -- it’s a class definition that just happens to be defined inside another class. That way, std::vector::iterator and std::map::iterator can have different implementations but both be called “iterator”.
std::pair is implemented as a struct, and as such its members (which are named first and second) are publicly accessible.
There’s nothing wrong that I can see with what you’ve done. insert will insert duplicate values (which isn’t an issue here), whereas try_emplace won’t. And which type of loop you use (while vs do while vs for) is more often a matter of personal choice and comfort than anything else.
Ok, so here’s what I got so far. Now, given that this is a _total_ hackjob, and probably not as well thought through as it could be (at the moment, I am working on it), it works over a concatenation of two containers, vector, deque, list so on, but not on two different containers, which is what I ultimately want. After doing some searching on the internet, I’ve come to realize that maybe I need to use PIMPL as idiom for the iterator, to be able to iterate over different containers, meaning one interface, holding a pointer to a baseclass, which gets derived into the implementation (if i’m not mistaken, this is what that basically would mean).
Anyway, this works so far, and any input would be greatly appreciated.
So basically, what I’m after here, is a container, holding two containers of the same value_type.
I think your MultiIterator type may just need to take two template types, one for each sub-iterator type, rather than assuming a single type.
Hi, is there any where I can get help/read up on how to create a multi-iterator? (and I need to learn, the concepts around it, so just saying "use boost" is not going to cut it, for me) By that I mean, kind of a iterator which you can use with STL algorithms, such that,
woud produce the output: 1 , 2 , 3 , 4 , 5 , 6
so.. here’s what I’ve come up with so far;
But I get stuck here… am I on the right path? Any help appreciated.
I’d have to think about this a lot more (and probably do a lot of experimentation myself) to say what the best way to do this would be, so I don’t think I can be of much help here. My advice would be that what you’re doing looks overcomplicated. I’d probably start by removing the templating and all of the complexity around pointer and reference types, and focus on making it work for with just std::vector<int>::iterator. Once you have that working, then you can figure out how to broaden this out to work with other iterator types.
In your last code example, under "Iterating through a map", you wrote:
cout << it->first << "=" << it->second << " ";
Since "first" and "second" are member functions, don’t they need to have parentheses at the end?
No, first and second are not member functions. They’re members of the pair. You can access them directly.
I’m still confused about this, because in the paragraph above this code example, you characterize first and second as member functions:
" std::pair allows access to the elements of the pair via the first() and second() member functions. In our map, we use first() as the key, and second() as the value."
My mistake -- they aren’t functions, they’re just normal members. I’ve updated the lesson accordingly.
Basically, std::pair looks something like this:
In the code under "Iterating through a vector", in the first comment, "an" should be "a".
Fixed, thanks!
Interesting, you use while loops to iterate through containers. **While** you are entitled to your opinion, **for** that I much prefer for loops.
Also what about the keyword ‘auto’ (c++11 onwards)? Could save on a lot of typing!
Maybe you could briefly talk about rbegin() and rend() as well.
<code>vector<int>::const_iterator</code>
does this mean that iterators belong to classes ?
It means const_iterator is a nested class inside of class vector.
How its possible to use "const_iterator" (that I understand, it’s a constant, and thereby, it can’t change), and even being constant, it remains being possible to cycle it with ++ or -?.
I can understand when you make the FIRST "++" or "-", you’re pointing to the "next" or "previous" memory address (as temporary address, since iterator is constant and cannot change), but not why this works for next iterations. If iterator pointer is constant, I understand the iterator should be using something like "iterator+n". But despite of to be constant, I see clearly not to be "read only".
So, in which sense "const_iterator" is really constant?. It is just about you can’t change iterator directly assigning it a position? (const_iterator = 3)?.
A const_iterator isn’t constant itself. Rather, it treats the values it is iterating over as const (and returns a const reference to them, instead of a normal reference).
Thus, a const_iterator is a good choice when you want a read-only iterator, because it will prevent you from changing the values you are iterating over.
Aaaah!, I see. Very smart. Thank you Alex, for getting me out of doubt.
Found some typos:
* "Operator-" should be "Operator--" (two hyphens): "Most iterators also provide Operator- to move to the previous element."
* "stl" should be "std": "(defined as an stl::pair)"
* "it’s" should be "its": "(which doesn’t provide an overloaded operator[] to access it’s elements directly)"
Fixed. Thanks!
I think you made a small typo in the conclusion, I’m still new to C++ but I just want to clarify. You wrote, "Iterators provide an easy way to step through the elements of a container class without having to understand how the container class is implemented.", and a bit after this you write, "the iterator does need to know how a class is implemented".
Isn’t this a contradiction or am I under-informed on the vocab you’re using? Thanks in advance.
Let me use an analogy here. You don’t have to know how your TV is built to use a TV remote, but your TV remote does need to know how the TV is built in order to send a command to it.
You don’t need to know how a class is implemented to use an iterator, but the iterator does need to know how the class is implemented to iterate through it.
Make sense?
When moving iterator to next element, pre-increment should be preferred, it’s more efficient on iterators.
You are correct. Article updated.
Somehow the syntax below appears to be asking for a static member variable called const_iterator; but const_iterator is obviously not a member variable, but the name of a type/class.
If we’ve previously seen the scope operator used this way, could someone help point out the chapter, thanks (is it that const_iterator is a class defined in the namespace of vector?)
A quick google has yet to produce accessible material that explains away this use of the scope operator; I’m most likely forgetting and missing something simple
It appears that this is an example of nested classes described here:
If this is wrong, please correct me
This version of const_iterator is a typedef defined in the public part of std::vector, so yes, const_iterator is essentially in the namespace of class std::vector.
typo?
"Most iterators also provide Operator- to move to the previous element." => Operator- ?
Edit: I see. I entered Operator dash dash and it is displayed as Operator dash. Weird.
How does the List version work?
while (it != li.end())
li.end is not efficient in a linked list.
The whole iterator seems completely wrong. It should be
while (!it.end())
Too much C hackery in the design.
If you’re talking about std::list, it’s usually implemented as a doubly-linked list, so end() is just your tail pointer.
Hi,
Which is better List or Vector? And when to use list and when to use vector?
It really depends on the needs of your application.
If you need random access to elements, probably Vector. If you need to insert a lot of elements and don’t need random access to the elements, probably List.
Just to add, We may insert element in map by directly giving it’s index. for example in the above mentioned program mymap[6]=”mango”; rather than to use mymap.insert(make_pair(6, “mango”));
Under “Iterating through a map” section, did you mean std:: pair instead of “stl::pair”? May be just a typo? Or does it mean, STL?
Name (required)
Website