consider this:
// set_iterator.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <iostream>
#include <set>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
set<int> a1;
set<int> a2;
a1.insert(3);
a1.insert(4);
a1.insert(5);
a2.insert(1);
a2.insert(2);
a2.insert(6);
set<int>::iterator iter;
int x = 0;
for (iter = a1.begin(); iter != a1.end(); ++iter)
{
if (x == 0) {
x = 1;
a1.insert(a2.begin(), a2.end());
}
cout << *iter << endl;
}
system("pause");
return 0;
}
goal is to visit each element of the set exactly once. i think the iterator is not valid after we insert elements into a1.
output is 3 4 5 6
1,2 are not printed.
how do we code such a situation.
Example 2: Iterate through Set using iterator() We have used the iterator() method to iterate over the set. Here, hasNext() - returns true if there is next element in the set. next() - returns the next element of the set.
You cannot access items in a set by referring to an index, since sets are unordered the items has no index. But you can loop through the set items using a for loop, or ask if a specified value is present in a set, by using the in keyword.
There is no way to iterate over a set without an iterator, apart from accessing the underlying structure that holds the data through reflection, and replicating the code provided by Set#iterator...
The key is to iterate in reverse order - then the added elements appear on the next iteration. Save this answer.
Actually, the iterator is still valid. A set is a node-based container.
The problem is that in a set the elements are always sorted. Before insertion, your set looks like this:
3 4 5
^
iter
After insertion, your set looks like this:
1 2 3 4 5 6
^
iter
You'll have to use a different container if you want to be able to do what you're doing.
i want to visit each element of the set exactly once as its size increases while traversal. any way to do this? – iamrohitbanga 1 hour ago
In your code, a1 = [3, 4, 5]. Then you get an iterator that points to the start of a1, which is '3'. Then you insert new elements into a1, resulting in [1, 2, 3, 4, 5, 6]. However, you're still pointing to the same value, '3'. So now you keep iterating and you'll print 3, 4, 5, 6.
It's still not clear why you'd want to insert the list after getting an iterator. Why can't you insert the elements before iterating over them, like @camh has mentioned?
If you still want to do this, use a vector since that will allow you to append elements to the end of the list, meaning that you'll still be pointing to '3', but the list will now be [3, 4, 5, 1, 2, 6] and those will print out in that order.
Or, add this:
for (iter = a1.begin(); iter != a1.end(); ++iter)
{
if (x == 0) {
x = 1;
a1.insert(a2.begin(), a2.end());
// Reset the iterator since we've modified the list
iter = a1.begin();
}
cout << *iter << endl;
}
This is ugly hacked code, and will only work in this specific circumstance. The better solution is @camh's. If you have some reason you can't do it that way, then we need more details.
The issue is not iterator validity.
The issue is that set does not have any defined order (although in this case, it's choosing sorted order, but I do not believe the complexity requirements of STL require that - another implementation may choose another order).
So any iterators are still valid after you call insert (so you may continue to deref the pointer and advance it and it is guaranteed to still reach end()). But any elements inserted may come 'before' your iterator and you will not see them unless you call begin() again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With