2015-08-31 2 views
4

У меня есть проблема с удалением элемента из set в пределах map под названием accesrightsByRank. Ключ от карты отличается ACCESRIGHT s: owner, modify, read и none. Значения map: set с именами аксессуаров с определенными ACCESRIGHT с.Как удалить элемент из набора внутри карты?

map<ACCESSRIGHT, set<string>>::const_iterator i; 
    set<string>::const_iterator j; 

    for(i = this->accessrightsByRank.begin(); i != this->accessrightsByRank.end(); i++){ 
     for(j = (*i).second.begin(); j != (*i).second.end(); j++){ 
      if((*j).compare(p_Username) == 0){ 
       i->second.erase(j); 
      } 
     } 
    } 

i->second Я думал, дал бы мне set, из которого я мог бы стереть имя пользователя, который больше не имеет определенного ACCESRIGHT, но мне кажется, я сделал что-то неправильно. Может кто-нибудь объяснить мне, почему это не работает, и как мне настроить свой код?

Это ошибка я получаю:

IntelliSense: нет экземпляра перегруженной функции «std::set<_Kty, _Pr, _Alloc>::erase_Kty=std::string, _Pr=std::less<std::string>, _Alloc=std::allocator<std::string>]» совпадает со списком аргументов и объект (объект имеет тип классификаторов, которые не позволяют обеспечить совпадение) типов аргументов являются: (std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<std::string>>>) типа объекта: const std::set<std::string, std::less<std::string>, std::allocator<std::string>>

+5

'' const_iterator' дает сопз набор & ', как' second' –

+1

@PiotrSkotnicki почему не отвечаешь? –

+4

Вы побеждаете всю цель 'map' и' set', если вам нужно сделать линейный поиск, просто говоря ... Вы должны использовать 'set :: find', а не линейный поиск. – PaulMcKenzie

ответ

3

Как указано в Piotr Skotnickihis comment, вы используете const_iterator. Только одно имя указывает, что такой итератор не позволяет изменять предмет, на который он указывает. Измените эти строки:

map<ACCESSRIGHT, set<string>>::const_iterator i; 
set<string>::const_iterator j; 

к этому:

map<ACCESSRIGHT, set<string>>::iterator i; 
set<string>::iterator j; 

для быстрейшего исправления. Однако после этого, рассмотрите все советы из комментариев по этому вопросу.

+0

Кроме того, вскрытие сообщений об ошибках действительно демонстрирует это как причину, поскольку тип объекта: 'const std :: set ' провозглашение отсутствия жизнеспособного метода стирания подтверждает этот анализ , – WhozCraig

+0

Спасибо за все советы, я обязательно запомню это! Но @BartoszKP, я думаю, вы имели в виду изменение 'map > :: const_iterator i;' to 'map > :: iterator i;' потому что набор разрешает использование const_iterators. – Laura

+0

@Laura. Действительно - вам нужно изменить оба. См. Мое обновление. – BartoszKP

3

Суммируя все комментарии,

  1. Вы изменяете карту и набор. Таким образом, вы должны использовать iterator, а не const_iterator.
  2. Чтобы удалить определенное значение в наборе, вам не нужен линейный поиск. std::set::erase() имеет вариант, который принимает значение, подлежащее удалению.
  3. i->second эквивалентен и легче читать, чем (*i).second.
  4. this-> является избыточным, за исключением случаев, когда у вас есть локальная переменная с тем же именем.

Объединить их, вы получите

map<ACCESSRIGHT, set<string>>::iterator i; 

for(i = accessrightsByRank.begin(); i != accessrightsByRank.end(); i++){ 
    i->second.erase(p_Username); 
} 
Смежные вопросы