std::forward_list erasing

I'm used to working with vectors but I'm trying other data structures for fun, below I am trying to remove an item in a forward list, it doesn't have erase, only erase after but I'm struggling to understand how it works and the simplest way to remove an item. In the code below, "it" is currently pointing at the element I want to delete (via investments) , what's the easiest way to delete it? My attempt currently crashes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        //class members
	std::unique_ptr<std::forward_list<shares>> stocks;
	std::unique_ptr<std::forward_list<shares*>> investments;


     //in member function
    (*it)->owned_shares -= amount;
		if ((*it)->owned_shares <= 0)
		{
			int i = std::distance(investments->begin(), it);
			auto pos = investments->begin();
			std::advance(pos, i);

			investments->erase_after(pos);
		}
Last edited on
If you are looping over the elements you could keep track of the iterator to the previous element and use that to erase the element.

Something like this (untested):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
std::forward_list<shares*>::iterator prev_it;
for (auto it = investments->begin();  it != investments->end(); ) 
{
	(*it)->owned_shares -= amount;
	if ((*it)->owned_shares <= 0)
	{
		if (it == investments->begin())
		{
			investments->pop_front();
			it = investments->begin();
		}
		else
		{
			it = investments->erase_after(prev_it);
		}
	}
	else
	{
		prev_it = it;
		++it;
	}
}


Edit: fixed use of invalidated iterator after erase (unfortunately it became a bit more complicated than I hoped)

Edit2: fixed mistake with comma instead of semicolon as pointed out by Enoizat
Last edited on
Thanks Peter87, that worked perfectly.
Sorry, Peter87, may I ask you what type of for-loop you are using?
1
2
// Shouldn’t this be a semicolon? \/
for (auto it = investments->begin(),  it != investments->end(); )

Enoizat, you are absolutely right. It should be a semicolon instead of a comma.
Ok, many thanks. I was just afraid there was a new syntax I had to study :-/
I just learned about before_begin() which allows us to simplify the code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
auto prev_it = investments->before_begin();
for (auto it = investments->begin();  it != investments->end(); ) 
{
	(*it)->owned_shares -= amount;
	if ((*it)->owned_shares <= 0)
	{
		it = investments->erase_after(prev_it);
	}
	else
	{
		prev_it = it;
		++it;
	}
}

https://en.cppreference.com/w/cpp/container/forward_list/before_begin
Topic archived. No new replies allowed.