Reputation: 25
My problem is, the for loop below always iterates only once.
Before entering the loop, the search_list size is always 1. But the search_list vector may grow inside the loop, and should iterate respectively in case some element is added to the list.
std::vector<int> search_list;
search_list.clear();
search_list.push_back(first_elem);
for(auto &discover : search_list)
{
......
if(&std::find(face_ids.begin(), face_ids.end(), i))
{
search_list.push_back(i);
}
......
}
How can I make this for loop to iterate multiple times based on that growing vector? Even though something is pushed to the search list, it does not iterate more than once. If something is added, it should set the discover to that element and re-enter the loop.
Upvotes: 2
Views: 3679
Reputation: 2446
Your problem is that the iterator is created when you begin the loop but is not updated then. You should do the for loop over an index :
std::vector<int> search_list;
search_list.clear();
search_list.push_back(first_elem);
for (int ii=0 ; ii < search_list.size() ; ii++) {
......
if(&std::find(face_ids.begin(), face_ids.end(), i))
{
search_list.push_back(i);
}
......
}
This way, if an element gets added, search_list.size()
will grow and the loop will go on since it will call it every time.
Be aware that if the if
statement is always verified, this would yield an infinite loop.
Edit: following the suggestion of Félix Cantournet, here is a version with a while
loop and some control that it cannot go infinite
int max_it = 1000;
int ii=0;
...
// i = MAGIC
...
while (&std::find(face_ids.begin(), face_ids.end(), i) && ii < max_it) {
search_list.push_back(i);
......
// i = NEW MAGIC
......
ii++;
}
Upvotes: 4
Reputation: 45454
The problem is that you not only change the end
of the list within the loop (which invalidates the use of a range-based for loop), but possibly also invalidate all iterators
of the list (which invalidates a iterator
based for loop.
Therefore, you must resort to something that will not be invalidated. The only thing fits this bill is the index. as in Math's answer.
However, this means that your algorithm is specific to using a vector
but not, say, a list
(when you could still use an iterator
-based for-loop).
Upvotes: 1
Reputation: 1974
Doing operations on a container that add or remove elements - or resize - can invalidate all iterators for that container.
A range based for loop assumes the iterators are not invalidated, so would give undefined behaviour if they are. Essentially, you'll need to resort to a traditional loop. Break out and restart the outer loop if the container is resized (e.g. place your outer loop in another loop that keeps going as needed).
It will typically involve restructuring your code but, usually, it is safer to avoid resizing a container within a loop that is iterating over the same container. There are few circumstances in practice where that is not possible.
Upvotes: 1