"Mike Pemberton" <mh*********@vodafone.net> wrote...
I'm sure there's a good explanation for this effect, but I get rather
a strange output from this little test:
#include <iostream>
#include <list>
int main()
{
std::list<int> int_list;
int_list.push_back(1);
int_list.push_back(2);
int_list.push_back(3);
int_list.push_back(4);
std::list<int>::reverse_iterator rev = int_list.rbegin();
while(rev != int_list.rend())
{
std::cout << *rev++ << std::endl;
int_list.pop_back(); // This line causes a problem.
}
return 0;
}
Output:
4
3
2
1
0
0
The inclusion of the int_list.pop_back() call seems to cause the two
additional iterations through the loop that print the two extra zeros.
If I comment out the int_list.pop_back() line the output is as
expected, and if i use a different conditional statement such as
while(! int_list.empty()) the output is also as expected.
Does anyone know why this doesn't work? Are there member functions of
std::list that shouldn't be used with iterators, reverse-iterators or
something?
Not sure off the top of my head, but at the time when you pop_back
the "last" element (at the moment when the list becomes empty), the
'rev' iterator may actually become screwed up.
Although the 'pop_back' is said to invalidate only the iterators and
references to the erased elements, the problem is that when pop_back
empties the list, iterators that used to be the same as the ends of
the list may become not the same any more, I think that's what you
are experiencing here.
For more clarification ask about it in comp.std.c++. FWIW, it could
be a defect in the Standard (the fact that it doesn't specify what
happens to the iterator which _is_ supposedly pointing 'one past the
end'.
Try this:
------------------------------------------------------------------
#include <string>
#include <iostream>
#include <list>
using namespace std;
int main()
{
list<int> int_list;
list<int>::reverse_iterator rev = int_list.rbegin();
cout << "'rev' is " << (rev == int_list.rend() ? "" : "NOT ")
<< "the same as 'rend()'\n";
cout << "Pushing '1'...\n";
int_list.push_back(1);
cout << "Resetting 'rev'...\n";
rev = int_list.rbegin();
cout << "'rev' is " << (rev == int_list.rend() ? "" : "NOT ")
<< "the same as 'rend()'\n";
cout << "'rev' points to " << *rev++ << std::endl;
cout << "After ++ ";
cout << "'rev' is " << (rev == int_list.rend() ? "" : "NOT ")
<< "the same as 'rend()'\n";
cout << "Popping the back\n";
int_list.pop_back(); // This line causes a problem.
cout << "'rev' is " << (rev == int_list.rend() ? "" : "NOT ")
<< "the same as 'rend()'\n";
string s;
getline(cin, s);
}
------------------------------------------------------------------
Victor