질문의 역사:
C++98의 STL에 등장한 반복자는 특정 데이터 구조에서 추상화할 수 있게 해주어 컨테이너 요소에 대한 통일된 접근을 제공했습니다. C++20이 도입되면서 standard ranges가 추가되어, 컨테이너 작업 시 표현력과 안전성이 더욱 향상되었습니다.
문제:
반복자와의 비정상적인 작업은 런타임 오류를 초래할 수 있습니다: 컨테이너 경계를 초과하거나 변경 후 무효화될 수 있습니다. 서로 다른 종류의 반복자 지원은 혼합될 경우 예기치 않은 동작을 초래할 수 있습니다. begin()/end()를 수동으로 작업하는 것은 규율이 필요합니다.
해결:
컨테이너의 기능에 맞는 반복자 유형을 사용해야 합니다(예: random access는 vector/deque/array에서만). 무효화된 반복자를 저장하지 마십시오. 현대적인 작업에서는 표준화된 ranges 및 알고리즘을 사용하는 것이 더 일반적입니다.
코드 예:
#include <vector> #include <algorithm> #include <iostream> #include <ranges> int main() { std::vector<int> vec{1, 2, 3, 4, 5}; // 반복자를 통한 반복 for (auto it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << " "; } // 범위를 통한 반복 for (int x : vec | std::ranges::views::filter([](int v){return v % 2 == 0;})) { std::cout << x << " "; } return 0; }
주요 특징:
push_back 호출 후 std::vector의 반복자는 어떻게 됩니까?
push_back 후 컨테이너의 용량이 증가하면(재조정), 모든 이전 반복자와 참조가 무효화됩니다. 용량 변경 없이 push_back 후에는 반복자가 유지됩니다. 수정 사이에 반복자를 저장하지 않는 것이 더 안전합니다.
random-access 반복자는 bidirectional 반복자와 무엇이 다릅니까?
Random-access는 산술( it + n ) 및 인덱스 접근(it[n])을 지원하며, bidirectional은 ++ 및 --만 지원합니다. 모든 STL 컨테이너가 random-access를 지원하는 것은 아닙니다.
표준 STL 알고리즘이 일반 포인터로 작업할 수 있습니까?
예, C++에서 포인터는 random-access iterator의 요구 사항을 완전히 충족합니다.
std::list의 반복기 내부에서 erase 메서드를 사용하여 직접 컨테이너를 변경하면 반복기가 업데이트되지 않아 런타임 오류가 발생합니다.
장점:
단점:
컨테이너를 변경하기 전에 항상 다음 반복기를 저장합니다. 벡터의 경우 erase-remove 이디엄 또는 리스트의 경우 list::remove_if와 같은 표준 알고리즘을 사용합니다.
장점:
단점: