How to loop in a vector (set, map, etc) from iterator i to iteratorj

T

Tony Young

Hi,

If I have a std::multimap<int, int> and two iterator it1 and it2
(obtained from multimap's equal_range()), how to loop the multimap from
it1 to it2? I have the following loop but don't know if there is a
better way? Please help. Thanks.

for(it=it1; it!=m.end();)
{
.....
it ++;
if (it == it2) // is it legal?
break;
}

Tony
 
E

Evan

There are two changes that can be made to clear up readability. First,
the traditional place for the increment is in the third part of the for
statement. So get rid of the it++ where it is and move it to there:

for(it=it1 ; it!=m.end() ; it++)

The second thing is that you are looping from it1 to it2, there's no
reason you need to compare against m.end() in the loop then later test
it against it2; it's sufficient to just put that test in the for loop:

for(it=it1 ; it!=it2 ; it++)

This also might fix a bug in you program now. I think that if what you
are searching for with equal_range isn't present in the multimap, your
code might break, depending on what you do in the omitted code. The
reason is that when the loop starts, it1 and it2 are equal, but neither
points to what you are looking for. So you do stuff as if it were
there. When you get to the end, you increment it, which is now past
it2, and it will never return. You'll run off the end of the container.
(I'm not positive about this all though.) Making the above change fixes
this if, in fact, it is broken.

Finally, the other comment I would add is that if you have something
like 'it++' as a statement (and thus don't really care whether you are
using 'it++' or '++it'), go with the prefix notation unless you find it
less readable. There will be a small improvement in the runtime speed*
because the prefix is slightly more efficient for non-primitive
datatypes. Assuming the functions are following the usual ++ semantics,
the postfix ++ must create a temporary object to return, while the
prefix ++ avoids this.

*A small improvement appears to be from about 2.5% with GCC -O2 and
about 5% with MSVC over the code I measured:
for( it=container.begin() ; it!=container.end() ; [++it or it++] )
*it = 0;
 
M

Mark P

Evan said:
*A small improvement appears to be from about 2.5% with GCC -O2 and
about 5% with MSVC over the code I measured:
for( it=container.begin() ; it!=container.end() ; [++it or it++] )
*it = 0;

It surprises me that an optimizing compiler can't easily recognize these
two as functionally identical. Clearly the result is dicarded at each
incrememnt. Is there more to this than meets the eye?
 
E

Evan

It surprises me that an optimizing compiler can't easily recognize
these
two as functionally identical. Clearly the result is dicarded at each
incrememnt. Is there more to this than meets the eye?

To figure out that it could, it'd have to make sure that neither the
constructor nor the destructor of the temporary have any side effects.
I don't know how difficult this is, but it'd probably take quite a bit
of work...
 
M

Mark P

Evan said:
To figure out that it could, it'd have to make sure that neither the
constructor nor the destructor of the temporary have any side effects.
I don't know how difficult this is, but it'd probably take quite a bit
of work...

Ah, good point. So I guess this can only be easily optimized for
built-in types?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,128
Latest member
ElwoodPhil
Top