Home    Personal    Work    Computers    Miscellaneous

LaTeX    Software Projects    Rendering Tutorial    UNIX Commands    Using CVS    Case Modding    Base Wiki

A foreach macro for C++ STL containers

Problem

I'm quite fond of using all kinds of C++ containers (such as a std::list or std::vector among many others). Even though iterators are available for these, it is still a bitch to repetitively type the following loop

for( std::vector< double >::iterator i = v.begin(); i != v.end(); ++i )

  // do something with *i

and

for( std::list< myType >::iterator j = l.begin(); j != l.end(); ++i )

  // do something with *j

whereas

foreach( i, v )

  // do something with *i

and

foreach( j, l )

  // do something with *j

would be a whole lot nicer and a lot more friendly on my irritation meter...

Solution

The following macro does exactly that:

#define foreach( i, c )\
  typedef __typeof__( c ) c##_CONTAINERTYPE;\
  for( c##_CONTAINERTYPE::iterator i = c.begin(); i != c.end(); ++i )

It is not known whether this contraption also works with different compilers than g++, because of the specific use of __typeof__, input is welcome on this matter.

Extensions

This macro can of course easily be extended with const and reverse iterators to create a const_foreach and a reverse_foreach:

#define const_foreach( i, c )\
  typedef __typeof__( c ) c##_CONTAINERTYPE;\
  for( c##_CONTAINERTYPE::const_iterator i = c.begin(); i != c.end(); ++i )

#define reverse_foreach( i, c )\
  typedef __typeof__( c ) c##_CONTAINERTYPE;\
  for( c##_CONTAINERTYPE::reverse_iterator i = c.rbegin(); i != c.rend(); ++i )

Other solutions

  • Boost also has a BOOST_FOREACH macro
  • You could use STL's templated std::for_each, but as this requires a functor to be created and passed with the std::for_each command, it does not serve our cause, i.e., writing a solution that is extremely short for repetitive typing

Credits

Kudos to the people (LIM, bmm) in ##c++ on irc.freenode.net.

Edit (locked) - History - Recent Changes - Search - Statistics
All contents copyrighted 2000-2006 Anthony Liekens unless otherwise noted. Powered by PmWiki
Page last modified on October 14, 2005, at 01:45 PM.