Thread: Remove element from STL list

  1. #1
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715

    Remove element from STL list

    Hello,
    please, I need to have a list of objects that are frequently inserted and removed.
    That's why I decided to use STL list.
    However, I have problems removing elements from the list.
    For example this code won't compile:
    Code:
    #include <iostream>
    #include <list>
    #include <string>
    
    using namespace std;
    
    struct Klijent
    {
    	string ime;
    };
    
    
    int main()
    {
    	Klijent k;
    	k.ime="Name";
    
    	list<Klijent>lista;
    
    	lista.push_back(k);
    
    	lista.remove(k);
    }
    One way to slove this is to use iterators:
    Code:
    for (it = lista.begin(); it != lista.end(); ++it)
    {
    	if (it->ime == "Name")
    	{
    		lista.erase(it);
    	}
    }
    but, this gives me an exception. I don't know what is wrong.
    I wonder if there is a clever way to do this?
    There's been a while since I used STL and I almost forget it.
    Thanks in advance.
    Last edited by Micko; 07-05-2007 at 07:35 AM.
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You would need to provide some way for remove() to compare objects, so you would provide an operator==
    Code:
    bool operator==(const Klijent& lhs, const Klijent& rhs)
    {
        return lhs.ime == rhs.ime;
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Of course, it makes sense now.
    Thanks laserlight
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    As for the other snippet, when you call erase(it), you invalidate the iterator. Subsequent incrementing of the iterator is undefined behaviour.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Massively Single Player AverageSoftware's Avatar
    Join Date
    May 2007
    Location
    Buffalo, NY
    Posts
    141
    If you needed to use the iterator method, erase() returns a valid iterator.

    So this:
    Code:
    if (it->ime == "Name")
    {
        it = lista.erase(it);
    }
    would work.
    There is no greater sign that a computing technology is worthless than the association of the word "solution" with it.

  6. #6
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Thank you people, very helpful...
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    But if you use the return value of it, the loop logic is broken. The "might-remove" loop is not simple. It looks like this:
    Code:
    for(container::iterator it = c.begin(); it != c.end(); ) {
      if(condition) {
        it = c.erase(it);
      } else {
        ++it;
      }
    }
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    Massively Single Player AverageSoftware's Avatar
    Join Date
    May 2007
    Location
    Buffalo, NY
    Posts
    141
    Quote Originally Posted by CornedBee View Post
    But if you use the return value of it, the loop logic is broken. The "might-remove" loop is not simple. It looks like this:
    Code:
    for(container::iterator it = c.begin(); it != c.end(); ) {
      if(condition) {
        it = c.erase(it);
      } else {
        ++it;
      }
    }
    Ouch, you're right. I thought it returned an iterator in such a way that allowed continued traversal. Looks like I'll be fixing some code tonight.
    There is no greater sign that a computing technology is worthless than the association of the word "solution" with it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  2. Reverse function for linked list
    By Brigs76 in forum C++ Programming
    Replies: 1
    Last Post: 10-25-2006, 10:01 AM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. link list
    By Unregistered in forum C++ Programming
    Replies: 4
    Last Post: 12-13-2001, 05:41 AM
  5. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM