Reputation: 68074
I have a BOOST_FOREACH loop to iterate over a list. Unfortunately, I also need to cache an iterator to a particular item.
typedef List::iterator savedIterator;
BOOST_FOREACH(Item &item, list)
{
// stuff...
if (condition)
savedIterator = &item; // this won't work
// do more stuff...
}
Obviously I can do this using a list.begin()..list.end() for loop, but I've grown to like BOOST_FOREACH. Is there a way round this?
Upvotes: 4
Views: 6087
Reputation:
i kind of wonder why people don't do this:
#define foreach(iter_type, iter, collection) \
for (iter_type iter = collection.begin(); iter != collection.end(); ++iter)
Upvotes: 1
Reputation: 3496
With Boost.Foreach, you're pretty much stuck with the reference to the dereferenced iterator since this is what Boost.Foreach was designed to do: simplify access to the elements in a range. However, if you're just looking for a single element that fits a criteria you might want to try std::find_if()
:
struct criteria {
template <class T>
bool operator()(T const & element) const {
return (element /* apply criteria... */)? true : false;
}
};
// somewhere else
List::iterator savedIterator =
std::find_if(list.begin(), list.end(), criteria());
It also looks like you want to apply operations on the whole list -- in which case I'll suggest using something like std::min_element()
or std::max_element()
along with Boost.Iterators like boost::transform_iterator
.
struct transformation {
typedef int result_type;
template <class T>
int operator()(T const & element) const {
// stuff
int result = 1;
if (condition) result = 0;
// more stuff
return result;
}
};
// somewhere else
List::iterator savedIterator =
std::min_element(
boost::make_transform_iterator(list.begin(), transformation()),
boost::make_transform_iterator(list.end(), transformation()),
).base();
Upvotes: 4
Reputation: 23145
This is not possible, as you do not have access to an iterator pointing to the current item inside the loop.
You could fetch an iterator from the list somehow using the current items data but I don't know if this is a good idea to follow, also performance-wise.
I'd suggest you use the solution you already proposed yourself with list.begin() .. list.end(), this is in my opinion the easiest to implement and recognize.
Upvotes: 8