C ++ iteration through a set

I recently changed the code to use a set instead of a vector:

std::set<b2Body *>toDestroy; //std::vector<b2Body *>toDestroy; 

But now I'm not sure how to iterate over a set to search for objects. This is what I had:

 std::vector<b2Body *>::iterator pos2; for(pos2 = toDestroy.begin(); pos2 != toDestroy.end(); ++pos2) { b2Body *body = *pos2; if (body->GetUserData() != NULL) { CCSprite *sprite = (CCSprite *) body->GetUserData(); [self removeChild:sprite cleanup:YES]; } _world->DestroyBody(body); } 

What is equivalent now that toDestroy is a collection? Based on Objective-C, so I'm just learning the best practices in C ++.

EDIT: adding error message:

 error: no match for 'operator=' in 'pos2 = toDestroy. std::set<_Key, _Compare, _Alloc>::begin [with _Key = b2Body*, _Compare = std::less<b2Body*>, _Alloc = std::allocator<b2Body*>]()' 
+4
source share
5 answers

You need to declare your iterator with the set tag:

Edit

 std::vector<b2Body *>::iterator pos2; 

to

 std::set<b2Body *>::iterator pos2; 
+5
source

With C ++ 11, you can simply write:

  for(auto pos2:toDestroy) 
+1
source

Iterating through the set will work just as if the vector were there, so there is no need to change the code.

I would pay attention to what happens in DestroyBody (does a call to an element from a vector or its installation, an invalid iterator?)

Also, the use of a vector, set, or list depends on the use of:

  • I would use a vector if the number of b2Body objects is known in advance, so the capacity can be reserved in advance, and new deletion of the insert does not occur often, or if you need random access to the vector element (without an iterator)
  • I would use a list if the number of elements is not known in advance and / or insertion and deletion often occur.
  • I would use a set if I need to iterate through an ordered list of elements or, for example, if I need an application to find if some data has already been processed and is in the set (the find method on the set runs quickly)

I think the list is the most suitable container here (and, nevertheless, the iterative code will not need to be changed)

0
source

It is worth a lot of titration types of containers with a type (especially when used inside a class).

 typedef std::set<b2Body *> BodyCont; //typedef std::vector<b2Body *> BodyCont; BodyCont toDestroy; 

Then your other code would not need to be modified:

 BodyCont::iterator pos2; 

If you can make typedef private, then you know that implementation details do not escape the class. If you need to make a typedef publication, then you know that you have implementation details and you need to understand why and if you can tighten your design.

0
source

Since C ++ 11, when iterating over a container, you should use "auto" to declare an iterator. In your case, the string β€œfor” can be written as follows: for (auto pos2 = toDestroy.begin (); pos2! = ToDestroy.end (); ++ pos2)

0
source

Source: https://habr.com/ru/post/1342186/


All Articles