tags:

views:

328

answers:

3

I'm trying to do the following without too much special case code to deal with invalidated POSITIONs etc:

What's the best way to fill in the blanks?

void DeleteUnreferencedRecords(CAtlMap<Record>& records)
{
   for(____;____;____)
   {
      if( NotReferencedElsewhere(record) )
      {
        // Delete record
        _______;
      }
   }
}
A: 

My first thoughts would be the save the current POSITION before calling GetNext, then, if you delete the element you can reset it. However, perhaps the safest way would be to create a new map containing the elements you want to keep, else you could be relying on how the internal implementation of POSITION works.

Rob
A: 

I'm not too familiar with CAtlMap, but if it's similar to the STL's map type, then Rob's "first thought" is safe -- deleting an item does not affect any iterators except the one(s) pointing to the item being deleted.

Head Geek
+2  A: 

According to this:

http://msdn.microsoft.com/en-us/library/0h4c3zkw(VS.80).aspx

RemoveAtPos has these semantics

Removes the key/value pair stored at the specified position. The memory used to store the element is freed. The POSITION referenced by pos becomes invalid, and while the POSITION of any other elements in the map remains valid, they do not necessarily retain the same order.

The problem is that the order can change -- which means that GetNext() won't really continue the iteration. It looks like you need to collect the POSITIONs you want to delete in one pass and delete them in the next. Removing a POSITION does not invalidate the other POSITION objects

Lou Franco
Yeah, this is what I ended up with. It does feel a bit crummy and inefficient so I was hoping there might be something better. Thanks for your answer.
Scott Langham