Multiple Iterators or just one?

Started by
5 comments, last by Storyyeller 12 years, 10 months ago
Hi,

I just want to know if it better to use different iterators for each for loop?

for example if I had a for loop to update the position of the sprites stored in a vector and another for loop to draw the sprites. Should I use the same iterator for both for loops or different?

I just want to know what the preferred way is.
Advertisement
Personally I tend to declare the iterator in the for statement of each loop. In practice I found its fairly rare for me to iterate over the same type in a given function anyway.

e.g.
[source lang="cpp"]
void MyClass::doSomthing()
{
for(std::vector<int>::const_iterator i = numbers.begin(); i != numbers.end(); ++ i)
...

for(std::vector<Groups>::iterator i = groups.begin(); i != groups.end(); ++i)
{
for(std::vector<Object>::iterator j = i->begin(); j != i->end(); ++j)
...
}
}
[/source]
Of course const_iterator and iterator could be a number of other things from integers to pointers depending on what im doing.

The only time I declare the iterator outside the loop is when I wish to access it outside the loop for some reason, but that rarely comes up.
Well, you should decouple updates from rendering, so....
Generally speaking scope the iterator inside the loop if possible. Re-using iterators would be like re-using loop counters, nothing technically wrong with it but counter intuitive and unnecessary.

One potential problem is illustrated with the following code:

i = list.begin();
while(i != list.end())
{
// use *i
++i;
}

// Later...

while(i != list.end())
{
// use *i
++i;
}

The second loop won't execute because we forgot to reset the iterator.
I've been watching Herb Sutter's lambda talks recently. If you have a compiler with C++0x lambda support, he would suggest something along the lines of

[source lang="cpp"]
std::for_each(container.begin(), container.end(), [/* external variables to capture go here */](container::value_type value)
{
...
// do stuff
...
});
[/source]

You don't need to advance the iterator yourself, it is handled by std::for_each The code also has some self documenting qualities (you are stating that this is for each element). You can keep the code close to the loop, unlike how you had to use std::for_each before lambda support (defined elsewhere in the code).

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]

Something about optimizing prematurely and the anti-christ.

I'm not 100% sure about how loops translate into machine code with iterators, but for numerical counters there should be no benefit to re-declaring counters for new loops. I would assume that modern compilers would optimize them to be pretty much the same.

If you have two loops operating over the same set of iterators in the same function it seems like you could just turn them into one loop somehow and not have the issue at all.

I've been watching Herb Sutter's lambda talks recently. If you have a compiler with C++0x lambda support, he would suggest something along the lines of

[source lang="cpp"]
std::for_each(container.begin(), container.end(), [/* external variables to capture go here */](container::value_type value)
{
...
// do stuff
...
});
[/source]

You don't need to advance the iterator yourself, it is handled by std::for_each The code also has some self documenting qualities (you are stating that this is for each element). You can keep the code close to the loop, unlike how you had to use std::for_each before lambda support (defined elsewhere in the code).


If you don't have C++0x lambda support yet, you can also use the BOOST_FOREACH macro.
I trust exceptions about as far as I can throw them.

This topic is closed to new replies.

Advertisement