반복자를 사용하여 벡터로 인덱스를 얻습니다
문제
벡터의 요소를 반복 할 때 인덱스 대신 반복자를 사용하는 것이 선호됩니다 ( 어레이 지수 대신 반복자를 사용하는 이유는 무엇입니까?).
std::vector<T> vec;
std::vector<T>::iterator it;
for ( it = vec.begin(); it != vec.end(); ++it )
{
// do work
}
그러나 루프 본문에서 인덱스를 사용해야 할 수도 있습니다. 이 경우 다음 중 성능 및 유연성/확장 성을 고려하여 다음 중 선호되는 것은 무엇입니까?
- 인덱스 루프로 되돌립니다
std::vector vec; size_t i; for ( i = 0; i < vec.size(); ++i ) { // use i }
- 오프셋을 계산합니다
std::vector vec; std::vector::iterator it; for ( it = vec.begin(); it != vec.end(); ++it ) { size_t i = it - vec.begin(); // use i }
- STD :: 거리를 사용하십시오
std::vector vec; std::vector::iterator it; for ( it = vec.begin(); it != vec.end(); ++it ) { size_t i = std::distance( vec.begin(), it ); // use i }
해결책
독점적으로 벡터를 사용할 계획이라면 반복자 루프보다 의도를 더 명확하게 전달하기 때문에 인덱스 루프로 다시 전환 할 수 있습니다. 그러나 향후 프로그램의 진화로 인해 컨테이너가 변경 될 수 있다면 반복자를 고수하고 모든 표준 반복자와 함께 작동하도록 보장되는 std :: 거리를 사용해야합니다.
다른 팁
STD :: 거리를 사용하는 것이 임의의 액세스 반복기뿐만 아니라 모든 반복자에 대해 작동하기 때문에 조금 더 일반적입니다. 임의의 액세스 반복기의 경우 Vec.begin ()만큼 빠르야합니다.
IT -VEC.BEGIN ()은 기본적으로 포인터 산술입니다.
std::distance(vec.begin(), it)
당신에게 색인을 줄 것입니다 it
그것을 가리키고 있다고 가정합니다 vec
.
칼
인덱스 루프로 되돌립니다.
기본적으로 90%의 경우 반복자가 우수하며, 이는 10% 중 하나입니다. 반복자를 사용하면 코드를보다 복잡하고 이해하기가 더 어려워지고 있습니다. 먼저 반복자를 사용하는 전체 이유는 코드를 단순화하는 것이 었습니다.
하나의 솔루션이 없습니다. 필요한 경우 인덱스를 유지하지만 루프 조건으로 사용하지 마십시오. 목록에서도 작동하며 비용 (루프 당)은 O (N) 및 추가 레지스터입니다.
나는 향후 개발 이유로 항상 반복자와 함께 유지하는 경향이 있습니다.
위의 예에서는 std :: set의 std :: vector를 교체하기로 결정한 경우 (아마도 고유 한 요소가 필요할 수도 있음) 반복자와 거리 ()를 사용하여 계속 작동합니다.
나는 모든 성능 문제가 무시할 수있는 시점까지 최적화 될 것이라고 확신합니다.
벡터의 경우 항상 정수 방법을 사용합니다. 벡터로의 각 인덱스는 배열 조회와 동일한 속도입니다. 값을 많이 사용하려면 편의를 위해 그 값에 대한 참조를 만듭니다.
벡터 반복자는 포인터 산술을 사용하여 목록을 반복하기 때문에 이론적으로 인덱스보다 약간 빠를 수 있습니다. 그러나 일반적으로 가독성은 최소한의 런타임 차이의 가치가 있음을 알 수 있습니다.
다른 컨테이너 유형에 반복기를 사용하고 때로는 루프 변수가 필요하지 않을 때도 있습니다. 그러나 루프 변수가 필요한 경우 루프를 입력하기가 더 어려워지는 것 외에는 아무것도하지 않습니다. (나는 C ++ 0X의 자동을 기다릴 수 없다 ..)