Loop access iterator BOOST_FOREACH

I have a BOOST_FOREACH loop to iterate over a list. Unfortunately, I also need to cache an iterator for a specific element.

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 list.begin () .. list.end () for the loop, but I started to like BOOST_FOREACH. Is there any way around this?

+4
source share
3 answers

This is not possible since you do not have access to an iterator pointing to the current element inside the loop.

You could get an iterator from the list using the data of the current elements, but I do not know if this is suitable for this purpose, as well as for performance.

I suggest you use the solution that you have already proposed to yourself using list.begin () .. list.end (), which, in my opinion, is the easiest to implement and recognize.

+7
source

With Boost.Foreach, you pretty much get stuck with a reference to a dereferenced iterator, since this is what Boost.Foreach was designed to: simplify access to elements in a range. However, if you are looking for only one element that matches the criteria, you can 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 across the entire list, in which case I 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(); 
+4
source

I wonder why people do not:

 #define foreach(iter_type, iter, collection) \ for (iter_type iter = collection.begin(); iter != collection.end(); ++iter) 
+1
source

Source: https://habr.com/ru/post/1285954/


All Articles