Which container would be suitable for this case?

Hello,

let's say, I want to have a container, that will have enemies(in game). Enemies can spawn there(added to container), and be killed(so they are deleted from container). Basically it should allow me to add element(can be push_back(), I don't mind where I add enemy), and delete element without any order(so no pop_back() or pop_front() ).

What is the container I look for?

Thanks in advance.
closed account (Dy7SLyTq)
vector. list would only work if you killed enemies in reverse order of their creation.
std::set<> or std::unordered_set<>
@DTS - Didn't you mean that I should use list, and that vector would work only if I killed them in reverse order? Following cplusplus.com :
Lists are sequence containers that allow constant time insert and erase operations anywhere within the sequence, and iteration in both directions.


@Borges - New to sets, but they look like it could be it. Gonna check them out.

Thank you guys!
closed account (Dy7SLyTq)
no i mean vector. you want to use a list for literally a list. what you want is a vector, however i have never used a set so idk if thats better
So should code look somewhat like this?

1
2
3
4
5
6
7
8
9
10
std::vector<Enemy> enemyVector;
//code...

for(auto it = enemyVector.begin(); it != enemyVector.end(); ++it)
{
  if( it->IsDead() )
  {
     enemyVector.erase(it);
  }
}

And thanks, didn't know about this functionality 'till now.
> So should code look somewhat like this?

No. It will result in undefined behaviour.

After you do enemyVector.erase(it);, that iterator it is no longer valid.

This is fine:
1
2
3
4
5
6
7
8
9
10
11
for(auto it = enemyVector.begin(); it != enemyVector.end(); /* ++it */ )
{
     if( it->IsDead() )
     {
         it = enemyVector.erase(it);
     }
     else
    {
         ++it ;
    }
}

though repeated calls to erase while iterating forward is inefficient for a vector.

If the Enemy objects are lightweight (inexpensive to move), use the canonical remove/erase idiom.

1
2
enemyVector.erase( std::remove_if( std::begin(enemyVector), std::end(enemyVector),
                   []( const Enemy& e ) { return e.IsDead() ; } ), std::end(enemyVector) ) ;


If not, use a std::list<> instead.


> New to sets, but they look like it could be it. Gonna check them out.

Check them out.
For your use-case, an associative container is probably more suitable than a sequence container.
Last edited on
Topic archived. No new replies allowed.