A possible solution is to use an object of class type to control the for loop.
class index { public: index(int i){value= i;} operator int(){return value;} index operator++() {return ++value;} private: int value; };
You can now write:
for(index i=0; i<10; ++i) fn(i);
This will work if fn takes an int but not if it takes int&.
Roger Woollett <rwoollett@cix.compulink.co.uk>
Here are a couple of alternatives for you:
for(int i=0; i<10; ++i) fn(int(i));
The inline construction of int(i) returns a (int const &) which would catch the coder's change.
Alternatively:
for(int i=0; i<10; ++i){ int const & ci = i; fn(ci); }
This has the advantage that the reference does not change and can be optimised out of the loop.
Andy Robb <Andy.ROBB@lyonnaisecable.com>
Many thanks to Andy and Roger for replying. Andy's solutions are great for the original problem if I were re-visiting the code for low impact (cost / risk) maintenance.
However, if I were writing some green field code, I'd prefer Roger's idea as it is a more object oriented solution, but I have yet to test its impact on speed. It would also have to be converted into a template in order to work with any type, STL iterators for example as well as POD types such as int.
Furthermore, this should work with the for_each template and this new template object should provide a wrapper for the requirements of a set to be iterated over and the function to be called via for_each, then one could write:
void fn( const int &i ) ; Iterate<int,0,10,fn>
or
std::list<int> i ; Iterate<std::list<int>,i.begin(),i.end(),fn>
Perhaps fn should be a member of Iterate, then it could read the index for itself rather than having to be passed in as a formal parameter...
Aaron Ridout <Aaron.Ridout@signal.co.uk>
Overload Journal #37 - May 2000 + Programming Topics + Letters to the Editor
Browse in : |
All
> Journals
> Overload
> 37
(7)
All > Topics > Programming (877) All > Journal Columns > LettersEditor (132) Any of these categories - All of these categories |