TITLE: Foreach functions and iterators [ I edited the format for some of the code to improve readability. -adc ] PROBLEM: hunter@s850.mwc.edu (David Hunter) There is a right and wrong way to use each C++ feature. IMHO iterators are one of the right ways. class set_of_integer { public: // call fn for every item in a set // void foreach(void (* fn)(int)); // create a set s that contains every element for which fn is true. // void select(bool (* fn)(int), set_of_integer& s); }; RESPONSE: ciemjw@shark.ssd.lmsc.lockheed.com (Jon Weygandt) In many cases I need to use other data in the processing of the collection, with the simple function there is no way to get the other data to it, example: void showAll(Display& display, GraphicsList& list) { GraphicsListIterator git(display); while(git) { git.next()->show(display); } } RESPONSE: kanze@us-es.sel.de (James Kanze), 17 May 94 Of course, normally you would pass a reference to a functor, rather than a pointer to function. This allows additional context to be passed. void showAll( Display& display , GraphicsList& list ) { class DisplayElem : public GraphicsList::ForeachFunctor { public : DisplayElem( Display& dst ) : theDisplay( dst ) {} virtual void each( GraphicsElem& obj ) { obj.show( theDisplay ) ; } private : Display& theDisplay ; } ; list.foreach( DisplayElem( display ) ) ; } Which idiom you prefer is largely a matter of personal taste. I come from a strongly procedural background (read: I have never used a functional language), and generally prefer to see iterators as first class objects. This is also probably more idiomatic for C++; simply compare the number of lines of code necessary in the two examples. On the other hand, if you consider an iterator for a tree structure, rather than a simple list, you'll have to admit that the functional technique is considerably easier to implement. BTW, both your version and the functional version will get into trouble with const-ness. For this reason, my first class data type iterators emulate indexes rather than pointers, e.g.: void showAll( Display& display , GraphicsList& list ) { for ( GraphicsList::Iterator i( list ) ; ! i.finished() ; ++ i ) list[ i ].show( display ) ; } To correctly emulate a pointer, you *must* provide two iterators, one to emulate `GraphicsElem*', and a second to emulate `GraphicsElem const*', which are two distinct types. With the indexing paradigm, one suffices, as the const-ness is part of the type of the "array" (list), not the type of the index. [...]