2013-05-22 2 views
2

우리 (모두) 알고, 반복자에 의해 요소, 포인터를 삭제하면, 예를 들어 반복자, 무효 : 무엇에 대한std :: map :: begin을 사용하여 std :: map :: erase를 호출하는 것이 안전합니까?

std::map<..> map_; 
std::map<..>::iterator iter; 
// .. 
map_.erase(iter); // this will invalidate `iter`. 

하지만, :

map_.erase(map_.begin()); 

이 안전을? map_.begin()은 (새로운) 맵의 첫 번째 요소를 가리키는 유효한 반복자입니까?

"테스트하기"는 해결책이 아닙니다.

답변

3

은 반복기가 아니지만 반복기를 반환합니다. 첫 번째 요소를 지운 후에 begin()은 다른 (유효한) 이터레이터를 반환합니다.

std::map<int, int> m; 
m[1] = 2; 
m[2] = 3; 
m.erase(m.begin()); // <- begin() points to 1:2 
std::cout << m.begin()->second; // <- begin() points to 2:3 now 
+0

아하 (Aha)는 이런 식으로 생각합니다. "begin()은 반복자가 아니고 반복자를 반환합니다." –

3

, 우리는 다음을 참조하십시오

모든 반복자 (pos가, 첫째, 마지막) dereferenceable입니다 , 유효해야 유효하지만없는 말() 반복자 (dereferencable )을 사용할 수 없습니다.

꽤 많은 질문에 대한 답변입니다. begin()에 의해 반환되는 한 이터레이터 은 참조 할 수 없으므로 std::map::erase()에서 사용할 수 있습니다. 좋은 방법은 다음 begin()std::map::erase에서 사용할 수 확인 경우는 동일하지 end()하는 경우를 확인하는 것입니다 확인 : 맵이 비어있는 경우 또는

if(map.begin() != map.end()) { 
    map.erase(map.begin()); 
} 

, 당신은 또한 확인할 수 있고, 경우에 std::map::erase를 사용 그것은

if(!map.empty()) { 
    map.erase(map.begin()); 
} 
+1

+1을 가리키면 해당지도는 비워 둘 수 없습니다. –

1

이 안전하지 않다?

예. 이 호출에 의해 반환 된 임시 반복자를 begin()으로 무효화하고 해당 반복자가 문 끝에서 삭제됩니다.

map_.begin()은 (새로운) 첫 번째 요소를 가리키는 유효한 반복자가 될까요?

예,지도가 비어 있지 않은 경우 예. 요소를 지우더라도 나머지 요소에 대한 새로운 반복자를 만들 수 있습니다. 지도를 사용할 수 없게 만듭니다.