Basically what I want to do is remove some of the pointers inside my vector, but I found out that it can be quite slow to do that in the middle of the vector.
So I have a vector that already has data inside:
std::vector<Class*> vec1; // This already contains pointers
I'll iterate through vec1 and will add some of the pointers to another vector (vec2): vec2.push_back(vec1.at(index))
Now I would like to do is something like vec1 = vec2
but I don't know if this is the better (effecient) way to do that.
What would be the best way to do that?
I tried:
While looping through vec1 simply erasing what I need to remove from it:
it = vec1.erase(it)
While looping through vec1 moving the last item to the actual index and poping_back
vec1.at(index) = vec1.back();
vec1.pop_back();
Setting some attribute on the object the pointer is pointing while looping through vec1 and than using std::remove_if
vec1.erase(std::remove_if(vec1.begin(), vec1.end(), shouldBeRemoved), vec1.end());
Now I'm trying to generate a new vector while looping through vec1 and adding the pointers I want to keep, then "swapping" or "moving" the contents of this new vector to vec1.
Apparently when doing it the 4th way, the pointers get invalidated :(
I would love to see what you guys suggest me. A big thank you to everyone that is willing to help!
You can just use std::remove_if
to conditionally remove items from a vector. This algorithm will shift items that need to be kept over to the front. Follow it up with a std::vector::erase
call to actually remove the items not shifted to the front.
This is similar to your option 3, but you don't need to set an attribute first - just use a predicate that determines if the item should be kept or not, and avoid having to pass over the vector twice.
If you don't want to do it in-place, but want to fill a new vector, then std::copy_if
does that.
Removing things from a vector should be done with the erase remove idiom
It is well covered here: https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom
The basic idea is to shift the elements first and then erase the unneeded items which is faster than erasing and shifting each individual element which is done as from the example with:
v.erase( std::remove( v.begin(), v.end(), 5 ), v.end() );
But in general: If you have a lot of add/erase steps in your algorithm, you should use a std::list where removing elements in the middle is much cheaper at all.
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