Iterating multimap with conditional statement

113 Views Asked by At

First of all, I'm using C++98/03

I'm iterating my multimap starting from the second element:

multimap<pair<string, string>, pair<string, int> >::iterator it = paths.begin();
it++;

I have a conditional statement: if first element of first pair in current iterator is equal to the first element of first pair in a previous iterator, then do something, eg. print these elements.

for(; it != paths.end(); it++) {
    if((*it).first.first == (*it--).first.first ) {
        it++;
        cout << (*it).first.first << " ";
        cout << (*it--).first.first << endl;
        it++;
    }
    else {
        it++;
    }
}

My question is how can I use a copy of an iterator instead of incrementing it back after every (*it--)?

2

There are 2 best solutions below

0
On BEST ANSWER

Just use another iterator:

 typedef multimap<pair<string, string>, pair<string, int> >::iterator iterator;
 for( iterator it = paths.begin(); it != paths.end(); ) {
     iterator prev = it++;
     if( it == paths.end() )
         break;
     if( prev->first.first == it->first.first ) {
         // output here
     }
 }

Note your code is incorrect, first of all it has UB as == is not sequenced. But even if you use different iterator on the left side, you would get wrong behaviour:

 iterator it1 = it;
 if((*it1).first.first == (*it--).first.first ) { // not UB anymore, but result is always true as you compare the same element
1
On

Create an utility similar to C++11's std::prev:

#include <algorithm>

template <class T>
T prev(T it)
{
    std::advance(it, -1);
    return it;
}

Then use it as follows:

for(; it != paths.end(); it++) {
    if((*it).first.first == prev(it)->first.first ) {
        cout << (*it).first.first << " ";
        cout << prev(it)->first.first << endl;
    }
    else {
        it++;
    }
}