A. D.
A. D.

Reputation: 758

What is the std::vector::iterator's index in the vector?

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

Answers (2)

Nikos Athanasiou
Nikos Athanasiou

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

Dietrich Epp
Dietrich Epp

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

Related Questions