Reputation: 758
I have an std::vector<Bullet> bullets
and in the for-loop below I want to remove a bullet from the vector if it's not alive anymore.
My plan is to remove the element with pop_back()
. If there are more than one element in the vector I want to first swap the element that is to be removed with the last element in the vector, and then call pop_back()
.
for (std::vector<Bullet>::iterator b = bullets.begin(); b != bullets.end(); ++b) {
if(!b->isAlive()) {
if (bullets.size() > 1) {
std::iter_swap(bullets + ..., bullets.end());
}
bullets.pop_back();
}
}
The problem is the first parameter in iter_swap
. I looked up http://www.cplusplus.com/reference/algorithm/iter_swap/ and the syntax for the first parameter is the vector + the position of the element.
How do I find out b
's index in the vector?
Upvotes: 0
Views: 162
Reputation: 31499
If the condition governing whether an element is to be removed or not is :
object->isAlive()
Then you should use an STL way to do the removal, namely the erase-remove idiom :
bullets.erase(std::remove_if(bullets.begin(), bullets.end(),
[](Bullet const& b) {
return !b.isAlive();
}), bullets.end());
Now, to answer your particular question an iterator's it
index in a vector v
can be obtained like so :
auto indx = std::distance(v.begin(), it);
Upvotes: 3
Reputation: 213318
There's an easier way to filter a std::vector
.
#include <algorithm>
auto part = std::remove_if(
bullets_.begin(),
bullets_.end(),
[](const Bullet &bullet) { return !bullet.isAlive(); });
bullets_.erase(part, bullets_.end());
This will partition the vector into the alive and dead bullets, and then you delete the segment with the dead bullets.
The std::remove_if()
function is like partition()
but only the order of the first partition is preserved.
Upvotes: 3