Reputation: 10153
I need to traverse the std::list
holding 2 last values,i.e if my list is [1,2,3,4,5,6]
iteration1 : v1 = 1, v2 = 2
iteration2 : v1 = 2, v2 = 3
iteration3 : v1 = 3, v2 = 4
iteration4 : v1 = 4, v2 = 5
iteration5 : v1 = 5, v2 = 6
I tried to
auto next = _contour.begin();
auto prev = next;
while( next != _contour.end())
{
prev = next;
next++;
}
But it doesn't work good - there is a problem at the end of traverse. In the last iteration next
is pointing outside the list.
How can I do this correctly with good performance I don't want at each iteration check next
?
Upvotes: 0
Views: 71
Reputation: 169018
The problem, as you've hinted at, is that you check if next != _contour.end()
before incrementing it, and after incrementing it you cannot be certain that it's not equal to the end iterator.
To solve this problem, switch around the logic in your loop such that you test the new value of next
before each iteration.
For example:
auto current = _contour.begin();
// Make sure the list isn't empty before we go charging ahead.
if (current != _contour.end()) {
decltype(current) prev;
while ((prev = current), (++current != _contour.end())) {
std::cout << "v1:" << *prev << " v2:" << *current << std::endl;
}
}
(Demo)
Upvotes: 2
Reputation: 14589
Your loop should have increment and check condition swapped around to not go out of bounds. It can be done in several ways, using various loops, e.g.
auto next = _contour.begin();
auto prev = next;
if( !_contour.empty())
while( ++next != _contour.end())
{
//std::cout << *prev << ":" << *next << std::endl;
prev = next;
}
Or one-liner for
:
if( !_contour.empty())
for(auto next = _contour.begin(), prev = next; ++next != _contour.end(); prev = next )
{
//std::cout << *prev << ":" << *next << std::endl;
}
Upvotes: 0