Ниже приводится класс и контейнер
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;
}
};
Как удалить объект из множества с именем name = «suri»;
Что я сделал?
std::remove(s.begin(), s.end(), nameIs("suri"));
функтор
struct nameIs {
nameIs ( std::string s ) : toFind(s) { }
bool operator() ( Student* st)
{ return st->name.compare(toFind) == 0; }
std::string toFind;
};
Но я получаю ошибку времени компиляции
Ошибка 2 ошибка C3892: «_Следующий»: нельзя присвоить переменную, которая является константой c: \ program files (x86) \ microsoft visual studio 10.0 \ vc \ include \ алгоритма 1816
Что я делаю не так?
Как удалить пользовательский объект, используя stl remove из набора контейнеров?
если вы посмотрите на это, *first == val
но на самом деле в твоем случае это должно быть *first->name == val
ну, ты можешь попробовать это
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, вы не можете судиться std::remove
потому что это требует, чтобы elemetns были назначаемыми.
Тем не менее, вы не нужно удалять:
std::remove
на самом деле не удаляет элементы из вашего контейнера, а только копирует все элементы, которые вы хотите оставить на переднем плане (см. стереть-удалить-идиомы). Для фактического удаления вы всегда должны использовать конкретный контейнер erase
функционировать в любом случае. Так что в вашем случае вы можете просто использовать find_if
в качестве замены remove
, Недостатком является то, что вы должны вызывать его несколько раз:
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"));
}
Такой алгоритм был предложил и добавлен в Основы библиотеки 2 TS. Если ваш компилятор поддерживает Library Fundamentals 2 TS, вы можете #include
<experimental/set>
и использовать std::experimetal::erase_if(s, nameIs("suri"))
,