LINUX.ORG.RU

C++: map + erase


0

0

Скажите плз, есть код типа такого:

multimap<int> foo;
multimap<int>::iterator it;

it = f.begin();

while (it != f.end())
{
    if (NeedToDelete(it))
         foo.erase(it);
    ++it; // Вот это корректно?
}

Вопрос такой, после удаления, it можно инкрементировать?

Дело в том, что смотрю кнугу по STL Плаугер, Степанов, Лии, там написано, что erase() возвращет итератор на элемент следующий за удаленным, однако в /usr/include/g++-3/multimap erase возвращает void.
И вот я сижу и не могу понять кто прав и как быть? Может кто-то подскажет?
anonymous

> Вопрос такой, после удаления, it можно инкрементировать?

Нет:

"erase members shall invalidate only iterators and references to the
erased elements."

Но, очевидно, можно его скопировать и инкрементировать копию до
удаления.

> Дело в том, что смотрю кнугу по STL Плаугер, Степанов, Лии, там
> написано, что erase() возвращет итератор на элемент следующий за
> удаленным, однако в /usr/include/g++-3/multimap erase возвращает
> void.

erase() возвращает итератор для sequence-контейнеров. Для ассоциативных
в стандарте прописан тип возврата void.

int19h ★★★★
()
Ответ на: комментарий от int19h

> Но, очевидно, можно его скопировать и инкрементировать копию до
> удаления.

Точнее, можно сделать так:

  foo.erase(i++);

int19h ★★★★
()
Ответ на: комментарий от int19h

>Но, очевидно, можно его скопировать и инкрементировать копию до >удаления.

Это тоже не решает проблемы. Куда будет указывать скопированный итератор? На какую-то дырку. И что в этой дырке будет? Какой-нибудь мусор.

то же самое с

foo.erase(it++);

оно ничем не отличается от

foo.erase(it); it++;

что в принципе у меня и есть.

Мда, то ли я чего-то не знаю, то ли это всё криво как-то.

anonymous
()

он работает точно также как если бы
it указывал на
struct map_item {void *data; map_item *next; };

надо вычислять "следущий" элемент до удаления.

anonymous
()
Ответ на: комментарий от anonymous

> Это тоже не решает проблемы. Куда будет указывать скопированный
> итератор? На какую-то дырку. И что в этой дырке будет? Какой-нибудь
> мусор.

Ты не понял. Ты сначала делаешь копию, потом ее инкрементируешь (при
этом оригинальный итератор остается нетронутым), а потом вызываешь
erase. Инвалидируется только оригинальный итератор.

> то же самое с
>
> foo.erase(it++);
>
> оно ничем не отличается от
>
> foo.erase(it);
> it++;

Не-а. Оно отличается принципиально, т.к. сначала делается копия it,
потом it двигается, а потом _копия_ (неинкрементированная!) передается
в erase.

int19h ★★★★
()
Ответ на: комментарий от int19h

>Ты не понял. Ты сначала делаешь копию, потом ее инкрементируешь (при >этом оригинальный итератор остается нетронутым), а потом вызываешь >erase. Инвалидируется только оригинальный итератор. Тут согласен на 100%, и более того, уже сделал. Огромное спасибо за подсказку.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.