2008-09-25 13 views
5

벡터 요소를 반복 할 때는 인덱스 대신 반복자를 사용하는 것이 좋습니다 (Why use iterators instead of array indices? 참조).반복자를 사용하여 벡터에 인덱스 가져 오기

std::vector<T> vec; 
std::vector<T>::iterator it; 
for (it = vec.begin(); it != vec.end(); ++it) 
{ 
    // do work 
} 

그러나 루프 본문에서 인덱스를 사용해야 할 수 있습니다. 성능 및 유연성/확장 성을 고려하여 다음 중 어느 것이 더 좋을까요? 인덱스 루프

  1. 되돌리기
     
    std::vector vec; 
    size_t i; 
    for (i = 0; i < vec.size(); ++i) 
    { 
        // use i 
    } 
    
  2. 계산은
     
    std::vector vec; 
    std::vector::iterator it; 
    for (it = vec.begin(); it != vec.end(); ++it) 
    { 
        size_t i = it - vec.begin(); 
        // use i 
    } 
    
  3. 사용 표준 : 거리
     
    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 
    } 
    
  4. 은 모든 반복자 작동하기 때문에 표준 : 거리를 사용하여 좀 더 일반적이다

답변

13

벡터를 독점적으로 사용하려는 경우 반복 루프보다 의도를 명확하게 전달하므로 색인 된 루프로 다시 전환 할 수 있습니다. 그러나 미래에 프로그램을 발전 시키면 컨테이너가 변경 될 수 있으므로 반복기를 고수하고 모든 표준 반복기에서 작동하도록 보장 된 std :: distance를 사용해야합니다.

8

오프셋 무작위 액세스 이터레이터 만이 아닙니다. 또한 랜덤 액세스 반복자의 경우 It - vec.begin()만큼 빠릅니다.

It - vec.begin()은 기본적으로 포인터 연산입니다.

4

인덱싱 된 루프로 되돌립니다.

기본적으로 90 %의 경우 반복기가 우수합니다. 이는 10 % 중 하나입니다. 반복기를 사용하면 처음부터 반복기를 사용하는 전체 이유가 코드를 단순화하는 것이므로 코드가 복잡해지고 이해하기가 어려워집니다.

+0

일반적으로 인덱스 된 루프가 더 나은 성능을 가지고 있다고 가정하는 것이 안전하지만 두 경우 모두 성능이 매우 비슷할 것이다. – Guvante

+0

나는 동의 할 수 없다. 루프의 본문에는 반복기를 참조 해제하는 다른 코드가 포함될 수 있습니다. 반복자는 코드를 단순하게 만들 의도가 없으며 코드를보다 일반적으로 만듭니다. 이터레이터를 사용하면 목록의 벡터를 바꿀 수 있으며 여전히 작동합니다. – QBziZ

+0

또한 std :: map 또는 std :: set 반복자는 매우 어리 석다. 가능한 모든 키를 반복하면 아마도 영원히 걸릴 것입니다. 또한 모든 키에 O (log (n)) 조회를 수행해야합니다. 따라서 루프는 O (m * log (n))를 취할 것입니다. 반복기를 사용하면 O (n) 시간에 컬렉션을 반복 할 수 있습니다. –

1

하나의 솔루션이 누락되었습니다 : 필요할 경우를 대비하여 색인을 보관하십시오. 그러나 루프 상태로 사용하지 마십시오. 목록에서 작동하며 비용 (루프 당)은 O (n)이고 추가 레지스터입니다.

0

나는 항상 미래의 개발을 위해 반복기를 사용하는 경향이 있습니다.

위 예제에서 반복자 및 거리()를 사용하여 std :: set (어쩌면 고유 한 요소 모음이 필요함)을 std :: vector 대신 교체하기로 결정했다면 계속 작동합니다.

나는 모든 성능 문제가 무시할 수있을 정도로 최적화 될 것이라고 확신합니다.

0

벡터의 경우 항상 정수 방법을 사용합니다. 벡터에 대한 각 인덱스는 배열 조회와 같은 속도입니다. 값을 많이 사용하려고한다면 편의를 위해 참조를 만듭니다.

벡터 반복기는 포인터 계산을 사용하여 목록을 반복하기 때문에 이론상 인덱스보다 약간 빠를 수 있습니다. 그러나 일반적으로 가독성은 최소한의 런타임 차이만큼 가치가 있음을 알게되었습니다.

반복자를 다른 컨테이너 유형에 사용하고 루프 변수가 필요하지 않은 경우가 있습니다. 그러나 루프 변수가 필요한 경우에는 루프를 입력하기 어렵게 만드는 것 외에는 아무 것도하지 않습니다. (나는 C++ 0x의 자동 ..을 기다릴 수 없다.)