C++: использование стирания в векторе итераторов

У меня возникла проблема с использованием функции стирания в C++.

У меня есть следующая структура:

typedef std::map<std::string,TreeElement> ObjMap;
class TreeElement {
    public:
        ObjMap::const_iterator parent;
        std::vector<ObjMap::const_iterator > children;
}

Теперь я пытаюсь удалить TreeElement из списка дочерних элементов его родителя, используя функцию стирания.

//Remove from parent
SegmentMap::const_iterator parent = segment->second.parent;
std::vector<SegmentMap::const_iterator >::const_iterator it = parent->second.children.begin();
for(;((*it)->first != segment->first) && (it != parent->second.children.end()); it++);
parent->second.children.erase(it); //Compilation fails

Это дает ошибку во время компиляции, указывающую, что он не может преобразовать

__gnu_cxx::__normal_iterator<const std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, TreeElement> >*, std::vector<std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, TreeElement> > > >

to

__gnu_cxx::__normal_iterator<std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, TreeElement> >*, std::vector<std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, TreeElement> > > >

Есть ли способ исправить это? Я попытался использовать итератор вместо const_iterator, но это просто переместило ошибку компиляции в

std::vector<SegmentMap::const_iterator >::iterator it = parent->second.children.begin();

Уточнение: я знаю, что функция стирания ожидает неконстантный итератор. Я ищу способ создать этот неконстантный итератор без изменения объявления parent и children в классе TreeElement.


person user1611565    schedule 20.08.2012    source источник


Ответы (2)


Parent является константным итератором, поэтому parent->second является константным, поэтому parent->second.children является константным, поэтому parent->second.children.begin() возвращает константный итератор.

erase ожидает неконстантный итератор.

person Šimon Tóth    schedule 20.08.2012
comment
И есть ли способ создать неконстантный итератор без изменения объявления родителя? - person user1611565; 20.08.2012
comment
@ user1611565 нет. Вы, конечно, можете отбросить const, но это очень некрасиво. Почему вы все равно хотите использовать const_interator, в коде нет ничего, что мешало бы вам использовать обычный итератор. - person Šimon Tóth; 20.08.2012
comment
В настоящее время я добавляю методы в существующую систему, в данном случае метод удаления. Я не должен менять класс TreeElement. - person user1611565; 20.08.2012
comment
@user1611565 user1611565 Удаление меняется. - person Šimon Tóth; 20.08.2012
comment
Я говорю об изменении объявления переменных, которые уже есть. Например: я не должен менять родителя ObjMap::const_iterator; к родителю ObjMap::iterator; - person user1611565; 20.08.2012
comment
@ user1611565 Ну, тогда вы по замыслу никак не можете изменить родителя. - person Šimon Tóth; 20.08.2012

Вы не можете сделать erase() при использовании const_iterator. Цель const_iterator — запретить модификацию vector каким-либо образом, включая стирание элементов через него. Вы должны использовать просто iterator, а затем исправить эту ошибку компиляции.

Тогда эта ошибка компиляции связана с тем, что вы пытаетесь присвоить const_iterator неконстантному iterator. Если вы измените и сделаете parent непостоянным iterator, ошибка должна исчезнуть.

person Lyubomir Vasilev    schedule 20.08.2012