how can I delete every second element from std::list in cpp? [closed]












1















I'm trying to delete every second element from std::list but I'm getting segment error (core dump) when I run erase().



#include <bits/stdc++.h>

using namespace std;

int main()
{
list <int> num_list;
list <int> :: iterator it;
num_list.push_back(1);
num_list.push_back(2);
num_list.push_back(3);
num_list.push_back(4);
num_list.push_back(5);
cout << num_list.size() << endl;
it = num_list.begin();
advance(it, 1);
for(it; it != num_list.end(); advance(it, 2)) {
num_list.erase(it);
}
for(it = num_list.begin(); it != num_list.end(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}









share|improve this question















closed as off-topic by Peter Ruderman, gsamaras, SergeyA, Neil Butterworth, dandan78 Nov 14 '18 at 8:18


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "This question was caused by a problem that can no longer be reproduced or a simple typographical error. While similar questions may be on-topic here, this one was resolved in a manner unlikely to help future readers. This can often be avoided by identifying and closely inspecting the shortest program necessary to reproduce the problem before posting." – Peter Ruderman, gsamaras, SergeyA, dandan78

If this question can be reworded to fit the rules in the help center, please edit the question.












  • 4





    where do you initialize it?

    – Stephan Lechner
    Nov 13 '18 at 16:31






  • 1





    Your advance(it, 2) call will run past the end of the list if it has an even number of elements. Your erase call also invalidates it, so advancing it afterwards is undefined behaviour.

    – Peter Ruderman
    Nov 13 '18 at 16:36








  • 4





    Unrelated: #include <bits/stdc++.h> should not be used (Why). using namespace std; should be avoided (Why). Together they amplify some of the other's worst effects and can result in some very odd errors.

    – user4581301
    Nov 13 '18 at 16:37






  • 3





    Why should this be closed? Deleting alternating elements is a non-trivial task (due to iterator invalidation). Somewhat surprisingly, it does not appear to be asked before. The code (now fixed) is pretty minimal and causes the error claimed, while the intent is also clear.

    – MSalters
    Nov 13 '18 at 16:51






  • 2





    @PeterRuderman: usually you'd do that with std::remove_if. That won't work here, though. So another reason why this isn't such a bad question.

    – MSalters
    Nov 13 '18 at 16:57
















1















I'm trying to delete every second element from std::list but I'm getting segment error (core dump) when I run erase().



#include <bits/stdc++.h>

using namespace std;

int main()
{
list <int> num_list;
list <int> :: iterator it;
num_list.push_back(1);
num_list.push_back(2);
num_list.push_back(3);
num_list.push_back(4);
num_list.push_back(5);
cout << num_list.size() << endl;
it = num_list.begin();
advance(it, 1);
for(it; it != num_list.end(); advance(it, 2)) {
num_list.erase(it);
}
for(it = num_list.begin(); it != num_list.end(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}









share|improve this question















closed as off-topic by Peter Ruderman, gsamaras, SergeyA, Neil Butterworth, dandan78 Nov 14 '18 at 8:18


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "This question was caused by a problem that can no longer be reproduced or a simple typographical error. While similar questions may be on-topic here, this one was resolved in a manner unlikely to help future readers. This can often be avoided by identifying and closely inspecting the shortest program necessary to reproduce the problem before posting." – Peter Ruderman, gsamaras, SergeyA, dandan78

If this question can be reworded to fit the rules in the help center, please edit the question.












  • 4





    where do you initialize it?

    – Stephan Lechner
    Nov 13 '18 at 16:31






  • 1





    Your advance(it, 2) call will run past the end of the list if it has an even number of elements. Your erase call also invalidates it, so advancing it afterwards is undefined behaviour.

    – Peter Ruderman
    Nov 13 '18 at 16:36








  • 4





    Unrelated: #include <bits/stdc++.h> should not be used (Why). using namespace std; should be avoided (Why). Together they amplify some of the other's worst effects and can result in some very odd errors.

    – user4581301
    Nov 13 '18 at 16:37






  • 3





    Why should this be closed? Deleting alternating elements is a non-trivial task (due to iterator invalidation). Somewhat surprisingly, it does not appear to be asked before. The code (now fixed) is pretty minimal and causes the error claimed, while the intent is also clear.

    – MSalters
    Nov 13 '18 at 16:51






  • 2





    @PeterRuderman: usually you'd do that with std::remove_if. That won't work here, though. So another reason why this isn't such a bad question.

    – MSalters
    Nov 13 '18 at 16:57














1












1








1








I'm trying to delete every second element from std::list but I'm getting segment error (core dump) when I run erase().



#include <bits/stdc++.h>

using namespace std;

int main()
{
list <int> num_list;
list <int> :: iterator it;
num_list.push_back(1);
num_list.push_back(2);
num_list.push_back(3);
num_list.push_back(4);
num_list.push_back(5);
cout << num_list.size() << endl;
it = num_list.begin();
advance(it, 1);
for(it; it != num_list.end(); advance(it, 2)) {
num_list.erase(it);
}
for(it = num_list.begin(); it != num_list.end(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}









share|improve this question
















I'm trying to delete every second element from std::list but I'm getting segment error (core dump) when I run erase().



#include <bits/stdc++.h>

using namespace std;

int main()
{
list <int> num_list;
list <int> :: iterator it;
num_list.push_back(1);
num_list.push_back(2);
num_list.push_back(3);
num_list.push_back(4);
num_list.push_back(5);
cout << num_list.size() << endl;
it = num_list.begin();
advance(it, 1);
for(it; it != num_list.end(); advance(it, 2)) {
num_list.erase(it);
}
for(it = num_list.begin(); it != num_list.end(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}






c++






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 16:35







Shaman Sharif Asif

















asked Nov 13 '18 at 16:28









Shaman Sharif AsifShaman Sharif Asif

273




273




closed as off-topic by Peter Ruderman, gsamaras, SergeyA, Neil Butterworth, dandan78 Nov 14 '18 at 8:18


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "This question was caused by a problem that can no longer be reproduced or a simple typographical error. While similar questions may be on-topic here, this one was resolved in a manner unlikely to help future readers. This can often be avoided by identifying and closely inspecting the shortest program necessary to reproduce the problem before posting." – Peter Ruderman, gsamaras, SergeyA, dandan78

If this question can be reworded to fit the rules in the help center, please edit the question.







closed as off-topic by Peter Ruderman, gsamaras, SergeyA, Neil Butterworth, dandan78 Nov 14 '18 at 8:18


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "This question was caused by a problem that can no longer be reproduced or a simple typographical error. While similar questions may be on-topic here, this one was resolved in a manner unlikely to help future readers. This can often be avoided by identifying and closely inspecting the shortest program necessary to reproduce the problem before posting." – Peter Ruderman, gsamaras, SergeyA, dandan78

If this question can be reworded to fit the rules in the help center, please edit the question.








  • 4





    where do you initialize it?

    – Stephan Lechner
    Nov 13 '18 at 16:31






  • 1





    Your advance(it, 2) call will run past the end of the list if it has an even number of elements. Your erase call also invalidates it, so advancing it afterwards is undefined behaviour.

    – Peter Ruderman
    Nov 13 '18 at 16:36








  • 4





    Unrelated: #include <bits/stdc++.h> should not be used (Why). using namespace std; should be avoided (Why). Together they amplify some of the other's worst effects and can result in some very odd errors.

    – user4581301
    Nov 13 '18 at 16:37






  • 3





    Why should this be closed? Deleting alternating elements is a non-trivial task (due to iterator invalidation). Somewhat surprisingly, it does not appear to be asked before. The code (now fixed) is pretty minimal and causes the error claimed, while the intent is also clear.

    – MSalters
    Nov 13 '18 at 16:51






  • 2





    @PeterRuderman: usually you'd do that with std::remove_if. That won't work here, though. So another reason why this isn't such a bad question.

    – MSalters
    Nov 13 '18 at 16:57














  • 4





    where do you initialize it?

    – Stephan Lechner
    Nov 13 '18 at 16:31






  • 1





    Your advance(it, 2) call will run past the end of the list if it has an even number of elements. Your erase call also invalidates it, so advancing it afterwards is undefined behaviour.

    – Peter Ruderman
    Nov 13 '18 at 16:36








  • 4





    Unrelated: #include <bits/stdc++.h> should not be used (Why). using namespace std; should be avoided (Why). Together they amplify some of the other's worst effects and can result in some very odd errors.

    – user4581301
    Nov 13 '18 at 16:37






  • 3





    Why should this be closed? Deleting alternating elements is a non-trivial task (due to iterator invalidation). Somewhat surprisingly, it does not appear to be asked before. The code (now fixed) is pretty minimal and causes the error claimed, while the intent is also clear.

    – MSalters
    Nov 13 '18 at 16:51






  • 2





    @PeterRuderman: usually you'd do that with std::remove_if. That won't work here, though. So another reason why this isn't such a bad question.

    – MSalters
    Nov 13 '18 at 16:57








4




4





where do you initialize it?

– Stephan Lechner
Nov 13 '18 at 16:31





where do you initialize it?

– Stephan Lechner
Nov 13 '18 at 16:31




1




1





Your advance(it, 2) call will run past the end of the list if it has an even number of elements. Your erase call also invalidates it, so advancing it afterwards is undefined behaviour.

– Peter Ruderman
Nov 13 '18 at 16:36







Your advance(it, 2) call will run past the end of the list if it has an even number of elements. Your erase call also invalidates it, so advancing it afterwards is undefined behaviour.

– Peter Ruderman
Nov 13 '18 at 16:36






4




4





Unrelated: #include <bits/stdc++.h> should not be used (Why). using namespace std; should be avoided (Why). Together they amplify some of the other's worst effects and can result in some very odd errors.

– user4581301
Nov 13 '18 at 16:37





Unrelated: #include <bits/stdc++.h> should not be used (Why). using namespace std; should be avoided (Why). Together they amplify some of the other's worst effects and can result in some very odd errors.

– user4581301
Nov 13 '18 at 16:37




3




3





Why should this be closed? Deleting alternating elements is a non-trivial task (due to iterator invalidation). Somewhat surprisingly, it does not appear to be asked before. The code (now fixed) is pretty minimal and causes the error claimed, while the intent is also clear.

– MSalters
Nov 13 '18 at 16:51





Why should this be closed? Deleting alternating elements is a non-trivial task (due to iterator invalidation). Somewhat surprisingly, it does not appear to be asked before. The code (now fixed) is pretty minimal and causes the error claimed, while the intent is also clear.

– MSalters
Nov 13 '18 at 16:51




2




2





@PeterRuderman: usually you'd do that with std::remove_if. That won't work here, though. So another reason why this isn't such a bad question.

– MSalters
Nov 13 '18 at 16:57





@PeterRuderman: usually you'd do that with std::remove_if. That won't work here, though. So another reason why this isn't such a bad question.

– MSalters
Nov 13 '18 at 16:57












3 Answers
3






active

oldest

votes


















9














Start from the second item: next(num_list.begin(), 1). The erase method returns an iterator to the next item of the removed item. So you can use just ++ operator to step 2.



int main()
{
list<int> num_list;
num_list.push_back(1);
num_list.push_back(2);
num_list.push_back(3);
num_list.push_back(4);
num_list.push_back(5);
cout << num_list.size() << endl;

for (auto it = next(num_list.begin(), 1); it != num_list.end();) {
it = num_list.erase(it);
if (it != num_list.end())
++it;
}
for (auto it = num_list.begin(); it != num_list.end(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}





share|improve this answer

































    7














    For a good explanation on why your approach does not work, see Stepan Lechner's answer.



    A completely different approach using std::remove_if and lambda expressions:



    int main() {
    std::list<int> ints{1, 2, 3, 4, 5};

    auto position = std::remove_if(ints.begin(), ints.end(),
    [counter = 0](const auto x) mutable {
    return ++counter % 2 == 0;
    });

    ints.erase(position, ints.end());

    for(const auto x : ints) {
    std::cout << x << ' ';
    }
    }


    std::remove_if, paired with erase methods calls, is the algorithm for removing particular elements from a range. Here, it gets a little tricky - we want to remove every second element, so we need a predicate, which will return true only for the even positions in the list. We achieve it using a member counter initialized with lambda init capture.



    EDIT: As correctly stated by MSalters in the comments, using std::list::remove_if is a superior solution to erase-remove idiom from <algorithm>. It takes advantage of internal std::list implementation, plus it's simply less awkward to type:



    // *ints* being the list itself
    ints.remove_if([counter = 0](const auto x) mutable {
    return ++counter % 2 == 0;
    });


    as opposed to the original:



    auto position = std::remove_if(ints.begin(), ints.end(),
    [counter = 0](const auto x) mutable {
    return ++counter % 2 == 0;
    });

    ints.erase(position, ints.end());





    share|improve this answer





















    • 3





      There's a std::list::remove_if which does not require the .erase.

      – MSalters
      Nov 13 '18 at 17:17











    • @MSalters that is indeed the superior solution. I have added that to my answer

      – Fureeish
      Nov 13 '18 at 17:24



















    4














    Erasing an element of a list invalidates the respective iterator, such that it must not be used for dereferencing or advancing any more. Iterators pointing to other elements than the erased one, however, are not affected.



    So you just need to remember an iterator position to be deleted and advance the original iterator before erasing the "toDelete"-position:



    int main()
    {
    list <int> num_list;
    num_list.push_back(1);
    num_list.push_back(2);
    num_list.push_back(3);
    num_list.push_back(4);
    num_list.push_back(5);

    size_t size = num_list.size();
    cout << size << endl;

    list <int> :: iterator it = num_list.begin();
    while(size--) {
    auto toDelete = it;
    it++;

    if (size%2==1)
    num_list.erase(toDelete);
    }

    for(it = num_list.begin(); it != num_list.end(); ++it) {
    cout << *it << " ";
    }
    cout << endl;
    return 0;
    }





    share|improve this answer



















    • 1





      A bit overkill to keep two state variables (size and it) but it works.

      – MSalters
      Nov 13 '18 at 16:55


















    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    9














    Start from the second item: next(num_list.begin(), 1). The erase method returns an iterator to the next item of the removed item. So you can use just ++ operator to step 2.



    int main()
    {
    list<int> num_list;
    num_list.push_back(1);
    num_list.push_back(2);
    num_list.push_back(3);
    num_list.push_back(4);
    num_list.push_back(5);
    cout << num_list.size() << endl;

    for (auto it = next(num_list.begin(), 1); it != num_list.end();) {
    it = num_list.erase(it);
    if (it != num_list.end())
    ++it;
    }
    for (auto it = num_list.begin(); it != num_list.end(); ++it) {
    cout << *it << " ";
    }
    cout << endl;
    return 0;
    }





    share|improve this answer






























      9














      Start from the second item: next(num_list.begin(), 1). The erase method returns an iterator to the next item of the removed item. So you can use just ++ operator to step 2.



      int main()
      {
      list<int> num_list;
      num_list.push_back(1);
      num_list.push_back(2);
      num_list.push_back(3);
      num_list.push_back(4);
      num_list.push_back(5);
      cout << num_list.size() << endl;

      for (auto it = next(num_list.begin(), 1); it != num_list.end();) {
      it = num_list.erase(it);
      if (it != num_list.end())
      ++it;
      }
      for (auto it = num_list.begin(); it != num_list.end(); ++it) {
      cout << *it << " ";
      }
      cout << endl;
      return 0;
      }





      share|improve this answer




























        9












        9








        9







        Start from the second item: next(num_list.begin(), 1). The erase method returns an iterator to the next item of the removed item. So you can use just ++ operator to step 2.



        int main()
        {
        list<int> num_list;
        num_list.push_back(1);
        num_list.push_back(2);
        num_list.push_back(3);
        num_list.push_back(4);
        num_list.push_back(5);
        cout << num_list.size() << endl;

        for (auto it = next(num_list.begin(), 1); it != num_list.end();) {
        it = num_list.erase(it);
        if (it != num_list.end())
        ++it;
        }
        for (auto it = num_list.begin(); it != num_list.end(); ++it) {
        cout << *it << " ";
        }
        cout << endl;
        return 0;
        }





        share|improve this answer















        Start from the second item: next(num_list.begin(), 1). The erase method returns an iterator to the next item of the removed item. So you can use just ++ operator to step 2.



        int main()
        {
        list<int> num_list;
        num_list.push_back(1);
        num_list.push_back(2);
        num_list.push_back(3);
        num_list.push_back(4);
        num_list.push_back(5);
        cout << num_list.size() << endl;

        for (auto it = next(num_list.begin(), 1); it != num_list.end();) {
        it = num_list.erase(it);
        if (it != num_list.end())
        ++it;
        }
        for (auto it = num_list.begin(); it != num_list.end(); ++it) {
        cout << *it << " ";
        }
        cout << endl;
        return 0;
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 13 '18 at 16:59

























        answered Nov 13 '18 at 16:53









        PeterPeter

        62618




        62618

























            7














            For a good explanation on why your approach does not work, see Stepan Lechner's answer.



            A completely different approach using std::remove_if and lambda expressions:



            int main() {
            std::list<int> ints{1, 2, 3, 4, 5};

            auto position = std::remove_if(ints.begin(), ints.end(),
            [counter = 0](const auto x) mutable {
            return ++counter % 2 == 0;
            });

            ints.erase(position, ints.end());

            for(const auto x : ints) {
            std::cout << x << ' ';
            }
            }


            std::remove_if, paired with erase methods calls, is the algorithm for removing particular elements from a range. Here, it gets a little tricky - we want to remove every second element, so we need a predicate, which will return true only for the even positions in the list. We achieve it using a member counter initialized with lambda init capture.



            EDIT: As correctly stated by MSalters in the comments, using std::list::remove_if is a superior solution to erase-remove idiom from <algorithm>. It takes advantage of internal std::list implementation, plus it's simply less awkward to type:



            // *ints* being the list itself
            ints.remove_if([counter = 0](const auto x) mutable {
            return ++counter % 2 == 0;
            });


            as opposed to the original:



            auto position = std::remove_if(ints.begin(), ints.end(),
            [counter = 0](const auto x) mutable {
            return ++counter % 2 == 0;
            });

            ints.erase(position, ints.end());





            share|improve this answer





















            • 3





              There's a std::list::remove_if which does not require the .erase.

              – MSalters
              Nov 13 '18 at 17:17











            • @MSalters that is indeed the superior solution. I have added that to my answer

              – Fureeish
              Nov 13 '18 at 17:24
















            7














            For a good explanation on why your approach does not work, see Stepan Lechner's answer.



            A completely different approach using std::remove_if and lambda expressions:



            int main() {
            std::list<int> ints{1, 2, 3, 4, 5};

            auto position = std::remove_if(ints.begin(), ints.end(),
            [counter = 0](const auto x) mutable {
            return ++counter % 2 == 0;
            });

            ints.erase(position, ints.end());

            for(const auto x : ints) {
            std::cout << x << ' ';
            }
            }


            std::remove_if, paired with erase methods calls, is the algorithm for removing particular elements from a range. Here, it gets a little tricky - we want to remove every second element, so we need a predicate, which will return true only for the even positions in the list. We achieve it using a member counter initialized with lambda init capture.



            EDIT: As correctly stated by MSalters in the comments, using std::list::remove_if is a superior solution to erase-remove idiom from <algorithm>. It takes advantage of internal std::list implementation, plus it's simply less awkward to type:



            // *ints* being the list itself
            ints.remove_if([counter = 0](const auto x) mutable {
            return ++counter % 2 == 0;
            });


            as opposed to the original:



            auto position = std::remove_if(ints.begin(), ints.end(),
            [counter = 0](const auto x) mutable {
            return ++counter % 2 == 0;
            });

            ints.erase(position, ints.end());





            share|improve this answer





















            • 3





              There's a std::list::remove_if which does not require the .erase.

              – MSalters
              Nov 13 '18 at 17:17











            • @MSalters that is indeed the superior solution. I have added that to my answer

              – Fureeish
              Nov 13 '18 at 17:24














            7












            7








            7







            For a good explanation on why your approach does not work, see Stepan Lechner's answer.



            A completely different approach using std::remove_if and lambda expressions:



            int main() {
            std::list<int> ints{1, 2, 3, 4, 5};

            auto position = std::remove_if(ints.begin(), ints.end(),
            [counter = 0](const auto x) mutable {
            return ++counter % 2 == 0;
            });

            ints.erase(position, ints.end());

            for(const auto x : ints) {
            std::cout << x << ' ';
            }
            }


            std::remove_if, paired with erase methods calls, is the algorithm for removing particular elements from a range. Here, it gets a little tricky - we want to remove every second element, so we need a predicate, which will return true only for the even positions in the list. We achieve it using a member counter initialized with lambda init capture.



            EDIT: As correctly stated by MSalters in the comments, using std::list::remove_if is a superior solution to erase-remove idiom from <algorithm>. It takes advantage of internal std::list implementation, plus it's simply less awkward to type:



            // *ints* being the list itself
            ints.remove_if([counter = 0](const auto x) mutable {
            return ++counter % 2 == 0;
            });


            as opposed to the original:



            auto position = std::remove_if(ints.begin(), ints.end(),
            [counter = 0](const auto x) mutable {
            return ++counter % 2 == 0;
            });

            ints.erase(position, ints.end());





            share|improve this answer















            For a good explanation on why your approach does not work, see Stepan Lechner's answer.



            A completely different approach using std::remove_if and lambda expressions:



            int main() {
            std::list<int> ints{1, 2, 3, 4, 5};

            auto position = std::remove_if(ints.begin(), ints.end(),
            [counter = 0](const auto x) mutable {
            return ++counter % 2 == 0;
            });

            ints.erase(position, ints.end());

            for(const auto x : ints) {
            std::cout << x << ' ';
            }
            }


            std::remove_if, paired with erase methods calls, is the algorithm for removing particular elements from a range. Here, it gets a little tricky - we want to remove every second element, so we need a predicate, which will return true only for the even positions in the list. We achieve it using a member counter initialized with lambda init capture.



            EDIT: As correctly stated by MSalters in the comments, using std::list::remove_if is a superior solution to erase-remove idiom from <algorithm>. It takes advantage of internal std::list implementation, plus it's simply less awkward to type:



            // *ints* being the list itself
            ints.remove_if([counter = 0](const auto x) mutable {
            return ++counter % 2 == 0;
            });


            as opposed to the original:



            auto position = std::remove_if(ints.begin(), ints.end(),
            [counter = 0](const auto x) mutable {
            return ++counter % 2 == 0;
            });

            ints.erase(position, ints.end());






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 13 '18 at 17:34

























            answered Nov 13 '18 at 17:06









            FureeishFureeish

            3,28321029




            3,28321029








            • 3





              There's a std::list::remove_if which does not require the .erase.

              – MSalters
              Nov 13 '18 at 17:17











            • @MSalters that is indeed the superior solution. I have added that to my answer

              – Fureeish
              Nov 13 '18 at 17:24














            • 3





              There's a std::list::remove_if which does not require the .erase.

              – MSalters
              Nov 13 '18 at 17:17











            • @MSalters that is indeed the superior solution. I have added that to my answer

              – Fureeish
              Nov 13 '18 at 17:24








            3




            3





            There's a std::list::remove_if which does not require the .erase.

            – MSalters
            Nov 13 '18 at 17:17





            There's a std::list::remove_if which does not require the .erase.

            – MSalters
            Nov 13 '18 at 17:17













            @MSalters that is indeed the superior solution. I have added that to my answer

            – Fureeish
            Nov 13 '18 at 17:24





            @MSalters that is indeed the superior solution. I have added that to my answer

            – Fureeish
            Nov 13 '18 at 17:24











            4














            Erasing an element of a list invalidates the respective iterator, such that it must not be used for dereferencing or advancing any more. Iterators pointing to other elements than the erased one, however, are not affected.



            So you just need to remember an iterator position to be deleted and advance the original iterator before erasing the "toDelete"-position:



            int main()
            {
            list <int> num_list;
            num_list.push_back(1);
            num_list.push_back(2);
            num_list.push_back(3);
            num_list.push_back(4);
            num_list.push_back(5);

            size_t size = num_list.size();
            cout << size << endl;

            list <int> :: iterator it = num_list.begin();
            while(size--) {
            auto toDelete = it;
            it++;

            if (size%2==1)
            num_list.erase(toDelete);
            }

            for(it = num_list.begin(); it != num_list.end(); ++it) {
            cout << *it << " ";
            }
            cout << endl;
            return 0;
            }





            share|improve this answer



















            • 1





              A bit overkill to keep two state variables (size and it) but it works.

              – MSalters
              Nov 13 '18 at 16:55
















            4














            Erasing an element of a list invalidates the respective iterator, such that it must not be used for dereferencing or advancing any more. Iterators pointing to other elements than the erased one, however, are not affected.



            So you just need to remember an iterator position to be deleted and advance the original iterator before erasing the "toDelete"-position:



            int main()
            {
            list <int> num_list;
            num_list.push_back(1);
            num_list.push_back(2);
            num_list.push_back(3);
            num_list.push_back(4);
            num_list.push_back(5);

            size_t size = num_list.size();
            cout << size << endl;

            list <int> :: iterator it = num_list.begin();
            while(size--) {
            auto toDelete = it;
            it++;

            if (size%2==1)
            num_list.erase(toDelete);
            }

            for(it = num_list.begin(); it != num_list.end(); ++it) {
            cout << *it << " ";
            }
            cout << endl;
            return 0;
            }





            share|improve this answer



















            • 1





              A bit overkill to keep two state variables (size and it) but it works.

              – MSalters
              Nov 13 '18 at 16:55














            4












            4








            4







            Erasing an element of a list invalidates the respective iterator, such that it must not be used for dereferencing or advancing any more. Iterators pointing to other elements than the erased one, however, are not affected.



            So you just need to remember an iterator position to be deleted and advance the original iterator before erasing the "toDelete"-position:



            int main()
            {
            list <int> num_list;
            num_list.push_back(1);
            num_list.push_back(2);
            num_list.push_back(3);
            num_list.push_back(4);
            num_list.push_back(5);

            size_t size = num_list.size();
            cout << size << endl;

            list <int> :: iterator it = num_list.begin();
            while(size--) {
            auto toDelete = it;
            it++;

            if (size%2==1)
            num_list.erase(toDelete);
            }

            for(it = num_list.begin(); it != num_list.end(); ++it) {
            cout << *it << " ";
            }
            cout << endl;
            return 0;
            }





            share|improve this answer













            Erasing an element of a list invalidates the respective iterator, such that it must not be used for dereferencing or advancing any more. Iterators pointing to other elements than the erased one, however, are not affected.



            So you just need to remember an iterator position to be deleted and advance the original iterator before erasing the "toDelete"-position:



            int main()
            {
            list <int> num_list;
            num_list.push_back(1);
            num_list.push_back(2);
            num_list.push_back(3);
            num_list.push_back(4);
            num_list.push_back(5);

            size_t size = num_list.size();
            cout << size << endl;

            list <int> :: iterator it = num_list.begin();
            while(size--) {
            auto toDelete = it;
            it++;

            if (size%2==1)
            num_list.erase(toDelete);
            }

            for(it = num_list.begin(); it != num_list.end(); ++it) {
            cout << *it << " ";
            }
            cout << endl;
            return 0;
            }






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 13 '18 at 16:49









            Stephan LechnerStephan Lechner

            28.4k32143




            28.4k32143








            • 1





              A bit overkill to keep two state variables (size and it) but it works.

              – MSalters
              Nov 13 '18 at 16:55














            • 1





              A bit overkill to keep two state variables (size and it) but it works.

              – MSalters
              Nov 13 '18 at 16:55








            1




            1





            A bit overkill to keep two state variables (size and it) but it works.

            – MSalters
            Nov 13 '18 at 16:55





            A bit overkill to keep two state variables (size and it) but it works.

            – MSalters
            Nov 13 '18 at 16:55



            Popular posts from this blog

            Full-time equivalent

            Bicuculline

            さくらももこ