This is somewhat "evil", but it has saved us from many bugs:
#define FOREACH(iter,stlContainer) \
for ( typeof(stlContainer.begin()) iter = stlContainer.begin(), \
iter##End_Cached = stlContainer.end(); \
iter != iter##End_Cached; \
++iter )
Using std::for_each
is generally preferable, but has some disadvantages:
- users must know a lot about the interactions between
bind1st
/ bind2nd
/ ptr_fun
/ mem_fun
to use it effectively for non-trivial "visitation" -- boost fixes a lot of these issues, but not everyone has or knows boost
- users may need to provide their own separate functor (usually a struct) for just a single point of use; said structs cannot be declared within the function surrounding the loop, leading to "non-locality" of related code -- it doesn't read as well as having the logic in-line with the flow of the rest of the function in some cases
- it doesn't always nicely inline, depending on compiler
The FOREACH macro as listed above provides a few things:
- like
std::for_each
, you won't get your boundary tests wrong (no iterating one past the end, etc)
- it will use
const_iterators
over constant containers
Note that it does require a somewhat nonstandard "typeof" extension.
A typical usage might be:
list< shared_ptr< Thing > > m_memberList;
// later
FOREACH( iter, m_memberList )
{
if ( (*iter)->getValue() < 42 ) {
doSomethingWith( *iter );
}
}
I'm not entirely happy with this macro, but it has been invaluable here, especially for programmers without as much experience in STL-aware design.
(Please feel free to point out pros/cons/flaws, I'll update the answer.)