Iterator Problem ( multimap )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
multimap<LONG, int*> subscriptionList;

void AddToMap(LONG eventId, int* Sub)
{
    subscriptionList.insert(pair<LONG, int*>(eventId, aSubscriber));
}

void RemoveFromMap(LONG eventId, int* unsubscriber)
{
pair<multimap<LONG,int*>::iterator,multimap<LONG,int*>::iterator>eventIdSubscriptions;

multimap<LONG,int*>::iterator        searcedSubscription;
multimap<LONG, int*>::iterator       subscription;
BYTE           subscriptionFound = FALSE;

    eventIdSubscriptions = subscriptionList.equal_range(eventId);

    for ( subscription  = eventIdSubscriptions.first;
          subscription != eventIdSubscriptions.second;
          subscription++                              )
    {
        if ( (*subscription).second == unsubscriber )
        {
            searcedSubscription = subscription;
            subscriptionFound   = TRUE;
        }
    }

    if ( subscriptionFound )
    {
        subscriptionList.erase(searcedSubscription);
    }

}


void TraversalInMap(Event* anEvent)
{
int *    aSubscriber;
LONG     eventId = 0;
pair<multimap<LONG,int*>::iterator,multimap<LONG,int*>::iterator> eventIdSubscriptions;
multimap<LONG,int*>::iterator  subscription;

    eventId              = anEvent->GetName();
    eventIdSubscriptions = subscriptionList.equal_range(eventId);

    for ( subscription  = eventIdSubscriptions.first;
          subscription != eventIdSubscriptions.second; )
    {
        aSubscriber = (*subscription).second;
        subscription++;
        aSubscriber->Inform(anEvent);
    }
}


aSubscriber->Inform(anEvent);

Problem is here! If Inform(anEvent) method will call RemoveFromMap or AddToMap method inside its class, we will lose the last location of iterator and the for-loop won't work correctly. How can we get the last iterator position after adding or deleting?

Thanks for your ideas.
Well, you could just save off an iterator to the next element before calling Inform(), but that works only if
Inform() and anything it calls "behaves nicely" and does not remove any other elements from the map.

A more general purpose solution, but far less efficient, is to copy the entire map to a local variable and
iterate across it. Then Inform() and code it calls is free to modify the subscription list in any way, as it
no longer affects the data structure you are iterating across. However, I don't know if that is the behavior
you intend.
I think it is hard to give advice without more comments on the design. The TraversalInMap function name doesn't tell me a lot about what that function's purpose is. Plus there is nowhere in that snip of code where subscriptionList could have been filled in the first place so looking at that small collection of code, it is difficult to understand the system design.

For instance, what is the purpose of Inform? What are you informing the existing subscribers for? If aSubscriber is found then it is already subscribed to the event in questions. So you are calling inform on aSubscriber for an event that aSubscriber is already subscribed to.
yeah exactly, inform method calls the existing subscribers. TraversalInMap method call alll the subcribers in multimap from begining to the end of multimap.
Topic archived. No new replies allowed.