2

I'm trying to iterate through a forward_list manually, and erase certain elements. My question is essentially the same as this one, but with a forward_list caveat.

The following code (for example only), despite not revisiting before after calling "erase after", does not work (it produces endless garbage).

#include <iostream>
#include <forward_list>

typedef std::forward_list<int>::iterator IT;

int main()
{
    std::forward_list<int> m{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    IT before = m.before_begin();

    for ( IT it = m.begin(); it != m.end(); ++it )
    {
        std::cout << *it;

        if ( *it % 2 == 0 )
        {
            m.erase_after( before );
        }

        before = it;
    }

    for( int i : m )
    {
        std::cout << i;
    }
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
c z
  • 7,726
  • 3
  • 46
  • 59
  • 1
    @Botje [Not really.](https://en.cppreference.com/w/cpp/container/forward_list/erase_after) – L. F. Aug 07 '20 at 10:17

1 Answers1

3

The problem is, after erase_after the iterator to the erased element, i.e. it becomes invalid; performing ++it later leads to UB.

erase_after returns the iterator to the element following the erased one, you can assign it to it. (And move ++it into the for statement to control it manually.)

typedef std::forward_list<int>::iterator IT;

IT before = m.before_begin();

for ( IT it = m.begin(); it != m.end(); )
{
    std::cout << *it;

    if ( *it % 2 == 0 )
    {
        it = m.erase_after( before );
    } 
    else
    {
        before = it;
        ++it;
    }

}

LIVE

StackAttack
  • 1,139
  • 1
  • 9
  • 15
songyuanyao
  • 169,198
  • 16
  • 310
  • 405