Reputation: 699
I found myself writing a hand-crafted while
-loop today like so:
std::list<T> foo; // In my case, map, but list is simpler
auto currentPoint = std::begin(foo);
while (true) {
// Let's say the container has > 0 elements
auto nextPoint = std::next(currentPoint);
if (nextPoint == std::end(foo))
break;
// Do stuff with *currentPoint and *nextPoint
currentPoint = nextPoint;
}
Following Sean Parent's advice (no raw loops), I tried to replace that while
-loop with a standard algorithm and a nice lambda, but I couldn't find a suitable algorithm that would iterate through the map on a sliding window (2-elements at a time). A simple for_each
with next
doesn't work, as for_each
passes a reference to the element to the lambda, and I can't call next
on it.
std::for_each(
std::begin(skylineMap),
// Let's say the container has > 0 elements
std::prev(std::end(skylineMap)),
[&](const typename decltype(skylineMap)::value_type ¤tPoint) {
auto nextPoint = ???; // next(currentPoint) wouldn't work, of course
// Do stuff with currentPoint and nextPoint
}
);
EDIT: Remove example of operation I wanted to do; the example seemed to confuse more than clarify.
Upvotes: 2
Views: 4016
Reputation: 283664
There are several options for doing this with pre-existing functions.
One is to use a zip-type function, such as the std::transform
overload with 5 arguments, and two ranges: [c.begin() + 1, c.end())
and [c.begin(), c.end() - 1)
. Or for_each
with boost::zip_iterator
. This is mostly only useful for windows of size 2.
Another is to use for_each
with boost::counting_iterator
, so that your callback actually receives an iterator that it can advance to access adjacent elements. This would be useful when your callback knows the size of the range it wants to use.
You can also combine them, using boost::zip_iterator
on boost::counting_iterator
to pass a [begin, end)
pair of iterators to the callback. That's useful because it lets the caller determine the window size.
For a one-off, I would just write the for-loop.
And finally, if you use this often you can package up that for-loop into your own algorithm function -- they are straight-forward templates. This will probably be have much lower complexity than using any of the above.
Upvotes: 3