oompahloompah
oompahloompah

Reputation: 9343

STL containers: iterating between two iterators

I am storing values in a std::map

I am finding two values in the map, and I want to iterate between the first through to the last item - however the <= operator is not implemented, so I can't do somethimng like this:

    void foobar(const DatedRecordset& recs, const double startstamp, const double endtstamp)
    {
        DatedRecordsetConstIter start_iter = recs.lower_bound(startstamp), end_iter = recs.lower_bound(endtstamp);

        // Can't do this .... (<= not defined)
        //for (DatedRecordsetConstIter cit = start_iter; cit <= end_iter; cit++ )

        / So have to resort to a hack like this:
        for (DatedRecordsetConstIter cit = start_iter; cit != recs.end(); cit++ ) {
            if ((*cit).first <= (*end_iter).first){
               //do something;
            }
            else
               break;
            }
       }
}

Is there a more elegant way of iterating between two known iterators?

Upvotes: 2

Views: 2381

Answers (6)

Judge Maygarden
Judge Maygarden

Reputation: 27613

Use != instead of <= and it will do what you want it to do.

void foobar(const DatedRecordset& recs, const double startstamp, const double endtstamp)
{
    DatedRecordsetConstIter start_iter = recs.lower_bound(startstamp),
                            end_iter = recs.upper_bound(endtstamp);

    for (DatedRecordsetConstIter cit = start_iter; cit != end_iter; ++cit) {
    }
}

Upvotes: 3

Christian Ammer
Christian Ammer

Reputation: 7542

If you want to include the end iterator in the loop, you can increment your end-condition iterator ++end_iter. After that the loop with cit != end_iter does the same as you intend to do with cit <= end_iter before incrementing.

Upvotes: 0

wilhelmtell
wilhelmtell

Reputation: 58715

struct ManipulateMatchingPairs {
    template<class K, class V>
    void operator()(const std::pair<K,V>& p) const {
        // do with p.second as you please here.
    }
};

// ...
std::for_each(start_iter, end_iter, ManipulateMatchingPairs());

Upvotes: 1

tbogdala
tbogdala

Reputation: 98

The STL for_each algorithm also will not include the ending iterator in the loop. You could always increcment end_iter and just use for_each so that it will be included, though.

 void foobar(const DatedRecordset& recs, 
             const double startstamp, 
             const double endtstamp)
{
    DatedRecordsetConstIter start_iter = recs.lower_bound(startstamp);
    DatedRecordsetConstIter end_iter = recs.lower_bound(endtstamp);
    if(end_iter != recs.end())
      ++end_iter;

    for_each(start_iter, end_iter, []()
       {
           //do something inside the lambda.
       });
}

Something like that maybe? I didn't give it a compile check ...

Upvotes: 0

Marlon
Marlon

Reputation: 20312

You have to use the != operator. I believe this is because a std::map isn't necessarily contiguous in memory (so the <= operator wouldn't make much sense, whereas a std::vector would), I could be wrong though

Upvotes: 0

Jeremiah Willcock
Jeremiah Willcock

Reputation: 30999

There isn't a <= operator for std::map<>::iterator, but using != on end_iter should do basically the same thing. If you want to include the end iterator itself in the iteration, use something like a do loop to do the != test at the end.

Upvotes: 1

Related Questions