Boost.Foreach is such a great piece of kit that once
you start using it you just can’t stop. Indeed I like working directly
with values rather than iterators so much that is feels normal for me to write
something like
BOOST_FOREACH( value_type x , make_iterator_range(
rbegin( seq ) , rend( seq ) )
whenever I wish to reverse iterate over a sequence. My
co-workers are not big fans of typing though, so they want a REVERSE_FOREACH. At
first naïve glance it looks easy to implement in terms of the original FOREACH:
template<typename C> inline iterator_range</*
something */> make_reverse_iterator_range(C& c)
{
return make_iterator_range( rbegin(c) ,
rend(c) );
}
#define REVERSE_FOREACH( x , container )
BOOST_FOREACH( x , make_reverse_iterator_range( container ) )
This works fine when container is an lvalue. But then
co-workers, used to the wonders of the original FOREACH, inevitably start to
use the new macro with rvalues and get a crash due to dangling references (–
the iterator_range’s members point to departed quantities…..) and if
you could somehow work around that, there is the issue hidden inside the “/*
something */” that you have to cope with fact that MSVC has no proper
const rvalue detection. Finally the
#define MACRO(x,y) ANOTHER_MACRO( f(x) , g(y) )
style is not recommended because they are brittle in
the face of x and/or y themselves being macros.
… but all these issues are exactly the ones
that BOOST_FOREACH itself solves! Thus surely it is technically possible to
write a REVERSE_FOREACH that works with rvalues as well as lvalues, e.g. by
essentially copying and pasting the FOREACH implementation and replacing “begin”
and “end” by “rbegin” and “rend” in the
vital places. However one feels there may be a better way… has anyone had
a go at creating a “fully-functional” REVERSE_FOREACH and could
offer me any advice? If indeed the task is fairly intricate and requires re-use
of foreach internals, would the library author consider including something in
the library itself?
Many thanks for reading,
Pete Bartlett