The following is a bit of “evil,” but it saved us from many mistakes.
(Update, thanks @ Ricky65 for the comment to bring me back here.) C ++ 11 has a range for the loop that far exceeds this if your compiler supports it; we are still working with some really old compilers.
#define FOREACH (iter, stlContainer) \
for (typeof (stlContainer.begin ()) iter = stlContainer.begin (), \
iter ## End_Cached = stlContainer.end (); \
iter! = iter ## End_Cached; \
++ iter)
(Further update, credit to Boost developers.) It is based on the more complex but more robust BOOST_FOREACH macro, but has the advantage of making debugging assemblies for smaller cases much easier, rather than requiring a small heap of forward headers (which are in some code bases / groups verboten).
Using std::for_each usually preferable, but has some disadvantages:
- users need to know a lot about the interactions between
bind1st / bind2nd / ptr_fun / mem_fun in order to use it effectively for a non-trivial “visit” - boost eliminates many of these problems, but not everyone has or knows boost - users may need to provide their own separate functor (usually a structure) for only one point of use; these structures cannot be declared inside the function surrounding the loop, which leads to the “nonlocality” of the associated code - it is not readable, and also has a logical sequence with the flow of the rest of the function in some cases
- it is not always beautifully built in, depending on the compiler
The FOREACH macro, as mentioned above, gives a few things:
- like
std::for_each , you will not be mistaken in your border tests (without repeating the end, etc.) - it will use
const_iterators over persistent containers
Note that this requires a somewhat non-standard type extension.
Typical uses may include:
list <shared_ptr <Thing>> m_memberList;
// later
FOREACH (iter, m_memberList)
{
if ((* iter) -> getValue () <42) {
doSomethingWith (* iter);
}
}
I am not completely satisfied with this macro, but here it was invaluable, especially for programmers who did not have much experience in STL design.
(Please feel free to indicate the pros and cons, I will update the answer.)
leander
source share