C ++: double iterating over a map

I would like to iterate over the map, but the inner loop will just loop through the top of the elements. With a vector it would look like this:

for(auto element1 = myVector.begin() ; element1 != myVector.end() ; ++element1){
    for(auto element2 = element1 + 1; element2 != myVector.end() ; ++element2){
         //my stuff
    }
}

      

But the display element1 + 1

returns an error no operator matches this operand

.. I suppose this is due to the item being out of order in the map.

So how could I do it right? I am currently using this dirty workaround, which requires a test in every loop:

for(auto element1 = myMap.begin() ; element1 != myMap.end() ; ++element1){
    for(auto element2 = element1; element2 != myMap.end() ; ++element2){
         if(element->first != element2->first)
         //my stuff
    }
}

      

+3


source to share


3 answers


You can use std::next

for this:

for(auto element1 = myMap.begin() ; element1 != myMap.end() ; ++element1) {
    for(auto element2 = std::next(element1) ; element2 != myMap.end() ; ++element2) {
        //my stuff
    }
}

      

Below is some additional background information about std::next

. std::next

has an optional second argument, which is the number of elements to iterate over later. For example, std::next(element1, 2)

will return an iterator for the second item after element1

. As pointed out in the comments, you have to be careful when using std::next

, especially in loops. If it it

points to an element before myMap.end()

, then use std::next(it, 2)

results in undefined behavior. You want to make sure that using this never goes through the end of the container.

You can think of std::next

it as if it were implemented like this:



// If distance is negative, then i must meet the requirements of BidirectionalIterator
// Otherwise, i must meet the requirements of ForwardIterator.
template<class ForwardIterator>
ForwardIterator next(ForwardInterator i, int distance) {
    for( ; distance < 0 ; ++distance) {
        --i;
    }
    for( ; distance > 0 ; --distance) {
        ++i;
    }

    return i;
}

      

Which can be implemented similarly:

template<class ForwardIterator>
ForwardIterator next(ForwardIterator i, int distance) {
    std::advance(i, distance);
    return i;
}

      

+7


source


The simplest solution would be to skip the first one:



for(auto element1 = myMap.begin() ; element1 != myMap.end() ; ++element1){
    for(auto element2 = element1; element2 != myMap.end() ; ++element2){
         if( element2 == element1 ) continue;
         //my stuff
    }
}

      

0


source


Even if you were unaware of some of the new features in C ++ like std::next()

(which is a good way to tackle this issue), this seems to be a pretty simple problem:

for(auto element1 = myMap.begin() ; element1 != myMap.end() ; ++element1){
    auto element2 = element1;
    ++element2;
    for(; element2 != myMap.end() ; ++element2){
         //my stuff
    }
}

      

0


source







All Articles