Как удалить пользовательский объект, используя stl remove из набора контейнеров?

Ниже приводится класс и контейнер

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 из набора контейнеров?

2

Решение

введите описание изображения здесь

если вы посмотрите на это, *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;
}
}
3

Другие решения

Как сказал @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"));
}
1

Такой алгоритм был предложил и добавлен в Основы библиотеки 2 TS. Если ваш компилятор поддерживает Library Fundamentals 2 TS, вы можете #include <experimental/set> и использовать std::experimetal::erase_if(s, nameIs("suri")),

0
По вопросам рекламы [email protected]