If we want to use BOOST_FOREACH to iterate over some new
collection type, we must "teach" BOOST_FOREACH
how to interact with our type. Since BOOST_FOREACH is built
on top of Boost.Range, we
must extend Boost.Range in
order to extend BOOST_FOREACH. The section Extending
Boost.Range explores this topic in detail.

Below is an example for extending BOOST_FOREACH to iterate
over a sub-string type, which contains two iterators into a std::string.

namespacemy{// sub_string: part of a string, as delimited by a pair
// of iterators
structsub_string{std::string::iteratorbegin;std::string::iteratorend;/* ... implementation ... */};// Add overloads of range_begin() and range_end() in the
// same namespace as sub_string, to be found by Argument-Dependent Lookup.
inlinestd::string::iteratorrange_begin(sub_string&x){returnx.begin;}inlinestd::string::iteratorrange_end(sub_string&x){returnx.end;}// Also add overloads for const sub_strings. Note we use the conversion
// from string::iterator to string::const_iterator here.
inlinestd::string::const_iteratorrange_begin(sub_stringconst&x){returnx.begin;}inlinestd::string::const_iteratorrange_end(sub_stringconst&x){returnx.end;}}namespaceboost{// specialize range_mutable_iterator and range_const_iterator in namespace boost
template<>structrange_mutable_iterator<my::sub_string>{typedefstd::string::iteratortype;};template<>structrange_const_iterator<my::sub_string>{typedefstd::string::const_iteratortype;};}

Now that we have taught Boost.Range
(and hence BOOST_FOREACH) about our type, we can now use
BOOST_FOREACH to iterate over our sub_string type.

my::sub_stringsubstr;BOOST_FOREACH(charch,substr){// Woo-hoo!
}

There are some portability issues we should be aware of when extending BOOST_FOREACH.
Be sure to check out the Portability
section. In particular, if your compiler does not support Argument-Dependent
Lookup, the Boost.Range
Portability section offers some suggested work-arounds.

For sequence types that are non-copyable, we will need to tell BOOST_FOREACH
to not try to make copies. If our type inherits from boost::noncopyable,
no further action is required. If not, we must specialize the boost::foreach::is_noncopyable<> template, as follows:

Even though we have to tell BOOST_FOREACH that our type
is non-copyable, that doesn't mean that BOOST_FOREACH
always makes a copy of our sequence type. Obviously, doing so would be expensive
and even wrong in some cases. BOOST_FOREACH is quite smart
about when to make a copy and when not to. The is_noncopyable<> trait is needed to elide the copy,
which is on a branch that might never get taken.

On some compilers, BOOST_FOREACH must occasionally take
a slightly slower code path to guarantee correct handling of sequences stored
in temporary objects. It asks itself, "Should I make a copy of this object?"
and later, "Did I make a copy or not?" For some types of sequences,
this is overkill. Consider a sequence which is a simple pair of iterators.
Jumping through hoops of fire to avoid copying it doesn't make sense because
copying it is so cheap.

A pair of iterators is an example of a lightweight proxy. It does not store
the values of the sequence; rather, it stores iterators to them. This means
that iterating over a copy of the proxy object will give the same results as
using the object itself. For such types, BOOST_FOREACH provides
a hook that lets us tell it not to worry about the expense of making a copy.
This can result in slightly faster loop execution. Simply specialize the boost::foreach::is_lightweight_proxy<> trait, as follows: