2

Following is the class and container

class student {
    std::string name;
    int id;
}

set<Student*, compare> s; // sorted by id that i have done correctly
class compare {
public:
    bool operator()( Student* s1, Student* s2) {
        return s1->id < s2->id;
    }
};

How to remove a object from set having some name = "suri";

What I did?

std::remove(s.begin(), s.end(), nameIs("suri"));

functor is

struct nameIs {
    nameIs ( std::string s ) : toFind(s) { }
    bool operator() ( Student* st)
    { return st->name.compare(toFind) == 0; }
    std::string toFind;
};

But I am getting compile time error Error 2 error C3892: '_Next' : you cannot assign to a variable that is const c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm 1816

What wrong am i doing? How to remove a customized object using stl remove from container set?

Suri
  • 3,287
  • 9
  • 45
  • 75

3 Answers3

3

enter image description here

if u look at it, *first == val but actually in ur case, it shud be *first->name == val

well , u can try this

std::set<Student*>::iterator it = s.begin();
for (it = s.begin(); it != s.end(); ) {
     if ((*it)->name == "suri") {
        s.erase(it++);
         break;
    }
    else {
        ++it;
    }
}
pola sai ram
  • 832
  • 7
  • 23
1

As @pola sai ram pointed out, you can't sue std::remove because that requires the elemetns to be assignable.

However, you don't need remove:
std::remove doesn't really remove elements from your container, but only copies all elments you want to keep to the front (see erase-remove-idiom). For the actual removal, you always have to use a container specific erase function anyway. So in your case, you can just use find_if as a replacement for remove. The drawback is that you have to call it multiple times:

auto it = std::find_if(begin(s), end(s), nameIs("suri"));
while (it != end(s)){
    it = s.erase(it);
    it = std::find_if(it, end(s), nameIs("suri"));
}
MikeMB
  • 20,029
  • 9
  • 57
  • 102
0

Such algorithm has been proposed and added to Library Fundamentals 2 TS. If your compiler supports Library Fundamentals 2 TS, you could #include <experimental/set> and use std::experimetal::erase_if(s, nameIs("suri")).

cpplearner
  • 13,776
  • 2
  • 47
  • 72