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

Credits

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


comments powered by Disqus