forward_list.erase_after seems to return an iterator to the erased element?

I am learning C++11 on my own using C++ Primer. I'm supposed to write a program using a forward_list<int>. The program should iterate through the forward_list, delete any even numbers and duplicate any odd numbers. It doesn't do that. The code bellow is littered with output that is unnecessary to the problem, but needed to show how my code goes against what I expected.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <forward_list>

using std::cout;
using std::endl;
using std::forward_list;

int main()
{
   forward_list<int> fw_lst = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
   
   cout << "Original forward list :" << endl;
   for(int i : fw_lst)
   {
       cout << i << ' ';
   }
   
   cout << endl;
   
   auto fw_list_curr = fw_lst.begin();
   auto fw_list_prev = fw_lst.before_begin();
   
   while(fw_list_curr != fw_lst.end())
   {
       if(*fw_list_curr % 2)
       {
           cout << "adding " << *fw_list_curr << endl;
           fw_list_curr = fw_lst.insert_after(fw_list_curr, *fw_list_curr);
           cout << "fw_list_curr before increment: " << *fw_list_curr << endl;
           
           if(fw_list_prev != fw_lst.before_begin())
           {
                cout << "fw_list_prev before increment: " << *fw_list_prev << endl;
           }
           else
           {
               cout << "fw_list_prev before increment: before first." << endl;
           }
           
           ++fw_list_curr;
           ++fw_list_prev;
           
           if(fw_list_curr != fw_lst.end())
           {
                cout << "fw_list_curr after increment:  " << *fw_list_curr << endl;
           }
           else
           {
               cout << "fw_list_curr after increment: after last" << endl;
           }
           cout << "fw_list_prev after increment:  " << *fw_list_prev << endl;
       }
       else
       {
           cout << "erasing " << *fw_list_curr << endl;
           fw_list_curr = fw_lst.erase_after(fw_list_prev);//this line is what seems to be broken.
           cout << "fw_list_curr " << *fw_list_curr << endl;
           
           if(fw_list_prev != fw_lst.before_begin())
           {
                cout << "fw_list_prev " << *fw_list_prev << endl;
           }
           else
           {
               cout << "fw_list_prev before first." << endl;
           }
       }
   
   cout << endl << "Modified forward list:" << endl;
   for(int i : fw_lst)
   {
       cout << i << ' ';
   }
   return 0;
}


As you can see from the output, I am failing to understand something about how forward_list works. Notice how it erases even elements twice. After erasing 2, fw_list_curr iterator should dereference to 3, but it dereferences to 2, and there is no 2 in the forward_list anymore. The same happen to all the following even numbers.

Original forward list :
0 1 2 3 4 5 6 7 8 9 
erasing 0
fw_list_curr 1
fw_list_prev before first.
adding 1
fw_list_curr before increment: 1
fw_list_prev before increment: before first.
fw_list_curr after increment:  2
fw_list_prev after increment:  1
erasing 2
fw_list_curr 2
fw_list_prev 1
erasing 2
fw_list_curr 3
fw_list_prev 1
adding 3
fw_list_curr before increment: 3
fw_list_prev before increment: 1
fw_list_curr after increment:  4
fw_list_prev after increment:  3
erasing 4
fw_list_curr 4
fw_list_prev 3
erasing 4
fw_list_curr 5
fw_list_prev 3
adding 5
fw_list_curr before increment: 5
fw_list_prev before increment: 3
fw_list_curr after increment:  6
fw_list_prev after increment:  5
erasing 6
fw_list_curr 6
fw_list_prev 5
erasing 6
fw_list_curr 7
fw_list_prev 5
adding 7
fw_list_curr before increment: 7
fw_list_prev before increment: 5
fw_list_curr after increment:  8
fw_list_prev after increment:  7
erasing 8
fw_list_curr 8
fw_list_prev 7
erasing 8
fw_list_curr 9
fw_list_prev 7
adding 9
fw_list_curr before increment: 9
fw_list_prev before increment: 7
fw_list_curr after increment: after last
fw_list_prev after increment:  9

Modified forward list:
1 3 5 7 9 9 

Last edited on
Why are you inserting elements?
Last edited on
I am supposed to duplicate odd elements and remove even elements.
OK, in that case the problem is that you are not updating fw_list_prev correctly after duplicating an odd number.
Yes I see it now! I wrote that section this way now, and it works:

1
2
fw_list_prev = fw_list_curr;
++fw_list_curr;


is it safe to assign iterators to others like that?
Yes, it is safe. What you wrote looks correct.
Then question closed, thank you for your patience!
No problem, and thank you for showing me the before_begin method which I didn't know about before. :-)
Topic archived. No new replies allowed.