CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    May 2015
    Posts
    500

    Erase an stl element within the or loop

    Hello

    I have the ollowing for loops, inside the second for loop, i want to erase the second element based on some condition.
    I know erasure invalidates the iterator. What is the nice way to do this ?

    Code:
    	for (auto& sulCell : nCellList.sulCellList)
    	{
    			bool bFirstMatch = false;
    
    			for (auto& tddCell : nCellList.tddCellList)
                             {
                                  if(condition)
                                   erase(tddCell);
                              }
           }

  2. #2
    Join Date
    Feb 2017
    Posts
    677

    Re: Erase an stl element within the or loop

    Quote Originally Posted by pdk5 View Post
    What is the nice way to do this ?
    If the "list" is an STL container it comes with an erase() method which can be used to erase elements from the container. How to do it is described in the documentation for each container but as far as I know it's done in the same way for all containers using iterators and a for-loop. It means you cannot use the range-based for-loop you had in mind but that's the only change you have to make in principle.

    This is the erase() documentation for std::list. See the "Erase all even numbers" example,

    https://en.cppreference.com/w/cpp/container/list/erase

    You can also go for the std-algorithms library. Then you end up using the Erase-Remove idiom:

    https://en.wikipedia.org/wiki/Erase%...93remove_idiom
    Last edited by wolle; May 26th, 2020 at 02:04 AM.

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Erase an stl element within the or loop

    From the code in post #1, the outer loop seems irrelevant in the context of the question asked - as the control variable isn't used?

    The important code is hence:

    Code:
    for (auto& tddCell : nCellList.tddCellList)
                             {
                                  if(condition)
                                   erase(tddCell);
                              }
    This is a common requirement and, as Wolle says in post #2, there are 2 ways of doing this. As erase invalidates iterator(s) (and which depends upon the type of container used), no method can be used that uses implied iterators - such as range-for does.

    Given a container c of numbers, the 2 methods are basically:

    Code:
    // Erase all even numbers
        for (auto it = c.begin(); it != c.end(); )
            if (*it % 2 == 0)    // Condition for erasure
                it = c.erase(it);
            else
                ++it;
    Note that there is no increment in the for statement. The iterator is only incremented if the erase condition is not true. If the element is erased, the return value from .erase() is the next element iterator (since C++11).

    The other way is to use the Erase-Remove idiom:

    Code:
    c.erase(std::remove_if(c.begin(), c.end(), [](auto n){return n % 2 == 0;}), c.end());
    where the lambda is the condition for removal.

    The Erase-Remove is the recommended way of doing this, as .erase() is usually expensive as it may involve shuffling memory (depending upon the type of container).
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured