Erase any element from the list while iterating

How can I remove any element from the list while iterating?
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
			std::list<std::string> l;

			l.push_back("b");

			for (auto it = l.begin(); it != l.end(); it++) {

                                if (*it == "b") {

			                l.push_back("d");
			                l.push_back("c");
			                l.push_back("a");

                                }

				if (*it == "d") {

					it = l.erase(it++); //or--it

					//But what if I want to delete current iterator, or "a" from "d" iterator.
					//I tried this it = l.erase(it); but it's not working. And I also tried std advance.

					//So the basicly mechanism would be: any element from the list can be removed while iterating.

				}

			}

Thanks :).
Last edited on
I think in this case the simplest solution is not to use a for loop.

1
2
3
4
5
6
7
8
9
    std::list<std::string> l = { "b", "d", "c", "a" };

    auto remove_me = "d";

    auto it = l.begin();
    while (it != l.end()) {
        if (*it == remove_me) it = l.erase(it);
        else ++it;
    }
Thanks for reply. But I wanted something like, if c is iterating then remove previous element like b.

if (*it == "c") it = l.erase(/*delete b element/*); */
Last edited on
Thanks for reply. But I wanted something like, if c is iterating then remove previous element like b.

Then you need to iterate over the list when it is referring to the "c" element, find the previous "b" element and remove that element from the list. Describing what you want to do in the general case might be more helpful than a specific one.
How do I write that code?
How do I write that code?

Well, if it were me:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <algorithm>
#include <list>
#include <string>


int main() {

    std::list<std::string> l = { "b", "d", "c", "a" };

    auto key = "d";
    auto lock = "b";

    auto key_pos = std::find(l.begin(), l.end(), key);

    if (key_pos != l.end()) {
        auto lock_pos = std::find(l.begin(), key_pos, lock);
        if (lock_pos != key_pos) l.erase(lock_pos);
    }
}


But if it were someone bent on not using all the tools available to them, a nested loop is likely the way to go. You've seen how to search for a single value in the list. All that is required is doing so twice.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <algorithm>

template < typename SEQ, typename X, typename Y >
SEQ& remove_all_x_before_last_y( SEQ& seq, const X& x, const Y& y )
{
    // 1. locate the last y
    const auto last_y = std::find( seq.rbegin(), seq.rend(), y ).base() ;

    // 2. erase all x that lies between begin and last_y (erase-remove idiom)
    //     https://en.wikipedia.org/wiki/Erase-remove_idiom
    seq.erase( std::remove( seq.begin(), last_y, x ), last_y ) ;
    
    return seq ;
}

http://coliru.stacked-crooked.com/a/ea8859b1cbf65c57
Topic archived. No new replies allowed.