0

I have a user-defined structure like this:

struct Cell{
   int dirty;
   double data;
   Cell* c;
 //  bool operator==(const struct Cell& other) {
 //   /* I am not sure if I need this function here...*/
 //  }
};

Then, I defined a list like this:

list<Cell> cell_list;

What I want to do is to delete any elements in "cell_list" that satisfy the condition

(certain_cell.dirty == 1)

Could anybody give me some instructions on how to effectively realize the above operations?

  • Use `remove_if`. Something like `cell_list.remove_if( [](Cell& c){return c.dirty;} );` And `dirty` should presumably be a `bool`. – ooga Jul 20 '15 at 01:46
  • 1
    @ooga Answers belong as answers. – Barry Jul 20 '15 at 01:52
  • @Barry It's such a trivial question that I thought I'd give the OP a chance to delete it. – ooga Jul 20 '15 at 01:58
  • @ooga Thank you for your reply. I am a C++ beginner so sorry about my silly question. I tried your method, but got " warning: lambda expressions only available with -std=c++11 or -std=gnu++11 " and " error: no matching function for call to 'std::list::remove_if(MyClass::myfunction(int*, int)::__lambda0)' cell_list.remove_if([](const Cell& c) {return (c.dirty == 1);}); " –  Jul 20 '15 at 02:04
  • @ooga Because I will probably add my codes to some bigger codes of others which won't use c++11 for compiling. How can I get around this error? –  Jul 20 '15 at 02:05
  • It's not a silly question. I just thought it might not be that useful to others. But I could be wrong! – ooga Jul 20 '15 at 02:14

3 Answers3

2

list actually has a member function named remove_if:

cell_list.remove_if([](const Cell& cell){
    return cell.dirty == 1;
});
Barry
  • 286,269
  • 29
  • 621
  • 977
  • Thank you for your quick reply, sir! But when I compile it. I got errors like this: " warning: lambda expressions only available with -std=c++11 or -std=gnu++11 " and " error: no matching function for call to 'std::list::remove_if(MyClass::myfunction(int*, int)::__lambda0)' cell_list.remove_if([](const Cell& c) {return (c.dirty == 1);}); " I know that maybe I compile it with "-std=c++11" can solve this, but is there any other way to get around this compile error? (I don't want to use c++11 because I will integrate my codes to someone else 's codes which are not compiled with c++11 ) –  Jul 20 '15 at 02:08
  • 1
    There are very little reason to stay compatible with C++03. Not only is it 12 years old, its also the previous-previous standard. There are not many compatibility issues with C++11, upgrading is usually a breeze. – sp2danny Jul 20 '15 at 02:24
2

To do it without lambdas (i.e., pre-C++11) :

#include <iostream>
#include <list>

struct Cell {
    bool dirty;
    Cell(bool dirt=false) : dirty(dirt) { }
};

typedef std::list<Cell> CellList;

bool isDirty(const Cell& c) {
    return c.dirty;
}

int main() {
    CellList cells;
    cells.push_back(Cell());
    cells.push_back(Cell());
    cells.push_back(Cell(true));
    cells.push_back(Cell());
    cells.push_back(Cell(true));

    for (CellList::const_iterator i=cells.begin(); i!=cells.end(); ++i)
        std::cout << i->dirty << '\n';
    std::cout << '\n';

    cells.remove_if( isDirty );

    for (CellList::const_iterator i=cells.begin(); i!=cells.end(); ++i)
        std::cout << i->dirty << '\n';
    std::cout << '\n';
}
ooga
  • 15,423
  • 2
  • 20
  • 21
  • Can I suggest `remove_if( &isDirty );` for readability instead. Just `isDirty` looks like you forgot to call the function. – sp2danny Jul 20 '15 at 02:34
0

This can be used for all containers, but may be quite inefficient on continuous containers such as vector. This can especially come in handy if you want to process all, and remove some elements of a list in one pass.

list<Cell> cells;
list<Cell>::iterator itr = cells.begin();
while( itr != cells.end() )
{
    if( itr->dirty == 1 )
        itr = cells.erase(itr);
    else
        ++itr;
}
sp2danny
  • 7,488
  • 3
  • 31
  • 53
  • There are algorithms to do this better. Writing a raw loop like this is inefficient and error-prone. – Barry Jul 20 '15 at 02:27