стереть максимальный элемент из набора STL - PullRequest
5 голосов
/ 27 июля 2010

Это продолжение моего предыдущего вопроса ( Сложность STL max_element ).

Я хочу получить элемент max из набора, но у меня проблемы.

Вот примерно мой код:

set<Object> objectSet;

Object pop_max_element() {
    Object obj = *objectSet.rbegin();
    set<Object>::iterator i = objectSet.end()--; //this seems terrible
    objectSet.erase(i); //*** glibc detected *** free(): invalid pointer
    return obj;
}

Ранее я пытался objectSet.erase(objectSet.rbegin());, но компилятор жаловался на то, что не было соответствующей функции (полагаю, ей не нравится reverse_iterator) Я знаю, что нет проверки пустого набора, но происходит сбой, когда objectSet.size () >> 0.

Ответы [ 3 ]

9 голосов
/ 27 июля 2010

Вы довольно близки, но вы пытаетесь сделать слишком много в этом назначении итератора.Вы применяете оператор после декремента к тому, что end возвращает.Я не совсем уверен, что это делает, но это почти наверняка не то, что вы хотите.Присвойте результат end i, а , затем уменьшите его, чтобы получить последний элемент набора.

set<Object>::iterator i = objectSet.end();
--i;
Object obj = *i;
objectSet.erase(i);
return obj;
5 голосов
/ 27 июля 2010

Оператор

set<Object>::iterator i = objectSet.end()--;

означает «назначить end () для i, а затем уменьшить временную переменную, которая должна быть выброшена».Другими словами, это то же самое, что и set<Object>::iterator i = objectSet.end();, и я уверен, что вы понимаете, что не можете стереть end (), потому что он указывает на один конец.Вместо этого используйте что-то вроде этого:

assert(!objectSet.empty()); // check there is something before end
set<Object>::iterator i = objectSet.end();
--i;
objectSet.erase(i);

, и это нормально, это законный способ по существу воспроизвести .back() для набора.

Кроме того, обратные итераторы имеют член base() дляпреобразовать в обычный итератор, и я думаю, что вы можете удалить только обычные итераторы - попробуйте objectSet.erase(objectSet.rbegin().base()).

5 голосов
/ 27 июля 2010

Вам нужно сделать это:

set<Object> objectSet;

Object pop_max_element() {
    Object obj = *objectSet.rbegin();
    set<Object>::iterator i = --objectSet.end(); // NOTE: Predecrement; not postdecrement.
    objectSet.erase(i); //*** glibc detected *** free(): invalid pointer
    return obj;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...