이터레이터는 STL 컨테이너의 요소를 포인터처럼 참조할 수 있게 해주는 객체입니다. 이들은 모든 컨테이너(벡터, 리스트, 맵 등)의 요소에 대한 통합된 액세스 방법을 제공합니다. 이터레이터는 여러 종류가 있습니다:
이터레이터의 생명 주기에 특별히 유의해야 합니다:
예제:
std::vector<int> v = {1,2,3,4,5}; for (auto it = v.begin(); it != v.end(); ++it) { if (*it == 3) { // 값이 3인 요소를 삭제합니다. it = v.erase(it); // erase는 다음 요소에 대한 이터레이터를 반환합니다. --it; // 필요 시 이터레이터를 조정합니다. } }
질문: std::vector::insert를 호출할 때 이터레이터가 무효화됩니까?
빈번한 답변: 아니요, 끝 범위를 초과하여 추가할 때만입니다.
정확한 답변: 삽입 위치보다 크거나 같은 모든 이터레이터와 참조가 무효화되며, 컨테이너의 용량이 증가할 경우에만 발생합니다. 용량이 충분하다면 — 삽입 지점 이후 범위의 이터레이터만 무효화됩니다.
예제:
std::vector<int> v = {1,2,3}; auto it = v.begin() + 1; v.insert(v.begin(), 0); // 여기서 it는 무효화될 수 있습니다!
이야기: 프로젝트에서 std::vector를 반복하기 위해 포인터를 사용했으며, push_back 후 무효화된 포인터를 이용하여 반복을 계속하며 애플리케이션이 충돌했습니다.
이야기: 개발자가 for(auto it : list)에서 erase를 통해 std::list의 요소를 삭제했으며, 반환된 erase 이터레이터를 사용하지 않았기 때문에 반복이 요소를 건너뛰었고 필요한 모든 요소가 삭제되지 않았습니다.
이야기: 코드에서 std::map을 사용했으며, 키를 기준으로 erase 후 이터레이터가 삭제된 요소에 묶여있어 (정의되지 않은 동작), 이후 접근 시 무작위로 실패했습니다.