Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Appending to a vector while iterating over it?

Tags:

I have a vector that I am iterating over. While iterating, I may append new values to the vector. It looks something like:

struct Foo {    bool condition; };  void AppendToVec(vector<Foo>& v) {    ...    v.push_back(...); }  vector<Foo> vec; ... for (vector<Foo>::size_type i = 0; i < vec.size(); ++i) {    if (vec[i].condition) AppendToVec(vec); } 

This works fine, and in fact elegantly handles the case where the newly appended elements recursively require even more elements to be added, but it feels a little fragile. If someone else comes along and tweaks the loop, it can easily be broken. For example:

//No longer iterates over newly appended elements vector<Foo>::size_type size = vec.size(); for (vector<Foo>::size_type i = 0; i < size; ++i) {    if (vec[i].condition) AppendToVec(vec); } 

or

//Vector resize may invalidate iterators for (vector<Foo>::iterator i = vec.begin(); i != vec.end(); ++i) {    if (vec->condition) AppendToVec(vec); } 

Are there any best practices to handle cases like this? Is commenting the loop with a "Warning: This loop is intentionally appends to the vector while iterating. Change cautiously" the best approach? I am open to switching containers too if that makes things more robust.

like image 502
JRM Avatar asked Aug 09 '10 19:08

JRM


People also ask

Can I append vector to a vector C++?

How do you append to a Vector in C++? Appending to a vector means adding one or more elements at the back of the vector. The C++ vector has member functions. The member functions that can be used for appending are: push_back(), insert() and emplace().

How do you append one vector to another vector?

To insert/append a vector's elements to another vector, we use vector::insert() function.

How do you increment an element in a vector?

Read a value into x , use that value as index into the vector, and increase the value at that index. So if the input for x is 1 , then it's equivalent to vec[1]++ , that is the second (remember that indexes are zero based) will be increased by one.

Can we add an element in the middle in vector?

Elements can be added in the middle of a Vector by using the java. util. Vector. insertElementAt() method.


2 Answers

My approach to this problem is often to create a queue to which I add any new elements, and then after iterating over the original container, process the elements in the queue and/or append them to the original.

The good points to this approach are that what is going on is obvious, and it works in scenarios where multiple threads could be enqueuing new elements.

like image 118
Kristopher Johnson Avatar answered Oct 12 '22 05:10

Kristopher Johnson


If someone else comes along and tweaks the loop, it can easily be broken.

Then don't use a for loop, use a while loop instead. For me, a for loop always implies a simple, iterative loop using a counter. However, if I encounter a while loop, I feel like things must have been too complicated to to express them in a simple for loop. I will look closer and I'm more careful with "optimizing" while loops than with for loops.

like image 39
sbi Avatar answered Oct 12 '22 05:10

sbi