2008-09-25 43 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 ::距離
     
    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 
    } 
    

回答

13

如果您打算專門使用矢量,您可能需要切換回索引循環,因爲它比迭代器循環更清楚地表達您的意圖。但是,如果將來的程序演化可能會導致容器發生變化,則應該堅持使用迭代器並使用std :: distance,這可以保證與所有標準迭代器一起工作。

8

使用std ::距離是有點更通用的,因爲它適用於所有的迭代器,不只是隨機訪問迭代器。在隨機訪問迭代器的情況下,它應該和它一樣快--vec.begin()。

它 - vec.begin()基本上是指針算術。

4

還原爲索引循環。

基本上在90%的情況下,迭代器是優越的,這是其中的10%。通過使用迭代器,使得代碼更復雜,因此難以理解,因爲首先使用迭代器的所有原因都是爲了簡化代碼。

+0

忘了提到性能,通常假設索引循環會有更好的性能是安全的,但在這兩種情況下性能會非常相似。 – Guvante 2008-09-25 09:39:32

1

您錯過了一個解決方案:在需要的情況下保留索引,但不要將其用作循環條件。也在列表上工作,成本(每個循環)是O(n)和一個額外的寄存器。

0

我總是傾向於保持迭代器的未來發展的原因。

在上面的例子中,如果你可能決定換出std :: set作爲std :: set(也許你需要一個唯一的元素集合),使用迭代器和distance()將繼續工作。

我很確定任何性能問題都會被優化到可以忽略的程度。

0

對於向量,我總是使用整數方法。向量中的每個索引與數組查找的速度相同。如果我打算使用這個值,爲了方便起見,我創建了一個參考。

矢量迭代器在理論上可能比索引稍快,因爲它們使用指針運算來遍歷列表。但是,通常我會發現可讀性值得最小的運行時間差異。

我使用其他容器類型的迭代器,有時候當你不需要循環變量時。但是,如果你需要循環變量,除了讓你的循環更難以輸入外,你什麼都不做。 (我不能等待C++ 0x的自動..)