2016-05-31 4 views
0

최근에 읽은 많은 수의 게시물 (for(const auto &it : vec))은 더 긴 이터레이터 구문 for(std::vector<Type*>::const_iterator it = vec.begin(); it != vec.end(); it++)을 사용하는 것과 같습니다. 그러나 나는 그들이 같지 않다고 말하는 this post에 왔습니다.const auto & iterator로 변환

현재, for 루프에서 요소를 지우려고하는 중입니다. const auto &it : nodesstd::vector<txml::XMLElement*>::iterator으로 변환하는 방법이 있는지 궁금합니다. 문제

코드 : 나는 확신 난 그냥 const를 포인터로 std::vector<txml2::XMLElement*>를 다시 작성할 수 있지만,이 코드는 단지 순간에 디버깅 때문에 안함 것

std::vector<txml2::XMLElement *> nodes; 
//... 
for (const auto &it : nodes) 
{ 
    //...  
    nodes.erase(it); 
} 

.

답변

4

루프를 기반으로하는 범위의 범위 선언을 반복기로 변환 한 다음 반복하는 동안 삭제하지 말아야합니다. iterating하는 동안 반복자를 조정하는 것은 위험하기 때문에 알고리즘에 의존해야합니다.

Erase-remove idom을 사용해야합니다.
remove_if과 함께 사용할 수 있습니다.


nodes.erase(std::remove_if(nodes.begin(), nodes.end(), [](auto it){ 

    //decide if the element should be deleted 
    return true || false; 

    }), nodes.end()); 
는 현재 기술 사양에 erase_if입니다 :

이 같이 보일 것입니다.

std::erase_if(nodes,[](auto it){ 

    //decide if the element should be deleted 
    return true || false; 
}); 
+0

감사합니다. 큰 도움이되었습니다. 결국'set_difference'를 사용하여 끝났지 만 올바른 경로로 나를 잡았습니다. – ZeroPhase

1

당신은 반복자하지만 요소에 대한 참조를하지 않습니다
이 위와 같은 동작의 깨끗한 버전입니다. std::find을 사용하기를 원하지 않는 한, iterator를 얻는 것은 꽤 어렵습니다.

벡터가 좋기 때문에 요소 당 카운터를 늘리고 반복자를 얻기 위해 nodes.begin() + counter을 수행 할 수 있습니다. 그러나 포인트를 무시할 수는 있습니다.

또한 루프에 대한 당신이 벡터의 종료 후 반복 발생합니다의 반복자를 삭제, 당신은이 코드를 테스트 할 수 있습니다

#include <iostream> 
#include <vector> 

using namespace std; 

int main() { 
    vector<int> v = {0,1,2,3,4,5,6}; 

    for (int x : v) { 
     cout << x << endl; 

     if (x == 2) { 
      v.erase(v.begin() + 2); 
     } 
    } 
    return 0; 
} 

당신이 반복자를 사용하려면, 단지 그들과 함께 루프를 할 또한 당신이 한 중간 루프를 삭제하려는 경우, 당신은 this answer을 수행 할 필요가 : 당신은 단지뿐만 아니라 작동 auto 반복자의 모든 유형을 지정할 필요가 없습니다

for (auto it = res.begin() ; it != res.end();) { 
    const auto &value = *it; 

    if (condition) { 
    it = res.erase(it); 
    } else { 
    ++it; 
    } 
} 

참고.