Program Tip

반복기를 사용하여 std :: map의 요소를 어떻게 삭제할 수 있습니까?

programtip 2020. 12. 15. 19:46
반응형

반복기를 사용하여 std :: map의 요소를 어떻게 삭제할 수 있습니까?


std::map내용에 따라 항목 을 반복 하고 삭제하고 싶습니다 . 이것이 최선의 방법입니까?


C ++ 11 호환 컴파일러가있는 경우 다음과 같이 쉽게 수행 할 수 있습니다.

std::map<K, V>::iterator itr = myMap.begin();
while (itr != myMap.end()) {
    if (ShouldDelete(*itr)) {
       itr = myMap.erase(itr);
    } else {
       ++itr;
    }
}

아이디어는 컨테이너의 시작에서 끝까지 반복기를 앞으로 걸어 가며 각 단계에서 현재 키 / 값 쌍을 삭제해야하는지 확인하는 것입니다. 그렇다면 erase멤버 함수 를 사용하여 반복 된 요소를 제거한 다음 맵의 다음 요소에 대한 반복자를 반환합니다. 그렇지 않으면 반복자를 정상적으로 앞으로 진행합니다.

C ++ 11 호환 컴파일러가 없거나 이전 코드베이스로 작업하는 경우 상황이 조금 더 까다 롭습니다. C ++ 11 이전에는 erase멤버 함수가 맵의 다음 요소에 대한 반복자를 반환하지 않았습니다. 즉, 반복하는 동안 요소를 제거하려면 세 부분으로 구성된 댄스를 사용해야합니다.

  1. 현재 반복기를 복사합니다.
  2. 현재 반복기를 다음 요소로 이동합니다.
  3. erase이전 반복자의 사본을 호출 하십시오.

이것은 여기에 표시됩니다.

std::map<K, V>::iterator itr = myMap.begin();
while (itr != myMap.end()) {
    if (ShouldDelete(*itr)) {
       std::map<K, V>::iterator toErase = itr;
       ++itr;
       myMap.erase(toErase);
    } else {
       ++itr;
    }
}

이 프로세스는 erase반복자 를 방금 호출 하면 무효화 되므로 증가 및 감소와 같은 작업이 정의되지 않은 동작으로 이어질 수 있기 때문에 필요 했습니다. 위의 코드는 이터레이터의 복사본을 설정 itr하고 다음 요소에 있도록 진행 한 다음 이터레이터의 임시 복사본을 지워이 문제를 해결합니다.

영리한 속임수를 사용하면 가독성을 희생하면서이 코드를 축소 할 수 있습니다. 다음 패턴은 이전 C ++ 코드에서 일반적이지만 C ++ 11에서는 필요하지 않습니다.

std::map<K, V>::iterator itr = myMap.begin();
while (itr != myMap.end()) {
    if (ShouldDelete(*itr)) {
       myMap.erase(itr++);  // <--- Note the post-increment!
    } else {
       ++itr;
    }
}

여기서 post-increment 연산자를 사용하는 것은 이전 반복자의 복사본을 만드는 영리한 방법입니다 (접미사 ++ 연산자는 원래 반복기 값의 복사본을 반환 함을 기억하십시오).


for(MyMap::iterator it = mymap.begin(); it!=mymap.end(); ) {
  if(mycondition(it))
    it = mymap.erase(it);
  else
    it++;
}

편집 : 이것은 MSVC에서만 작동하는 것 같습니다

edit2: in c++0x this works for associative containers too



This is one simple way:

    int value_to_delete( 2 );
    for( std::map<int, int>::iterator i = mm.begin(); i != mm.end(); ) {
        if( i->second != value_to_delete ) {
            mm.erase( i++ ); // advance before iterator become invalid
        }
        else {
            ++i;
        }
    }

ReferenceURL : https://stackoverflow.com/questions/4600567/how-can-i-delete-elements-of-a-stdmap-with-an-iterator

반응형