2011-02-15 60 views
2

我一直在使用地圖/矢量廣泛的這些天,但有一個疑問,在迭代他們
迭代矢量/地圖數據結構,C++

哪一個更好?

for(vector<string>::iterator it=myvec.begin(); it!=myvec.end(); ++it){ 
} 

for(int i=0; i < myvec.size(); i++){ 
     myvec[i] 
} 

首先,是他們打算做同樣的事情?

+1

更好的是什麼?你想訪問你的容器的元素? – knivil 2011-02-15 16:12:48

+0

我只想訪問元素以任何順序 – rda3mon 2011-02-15 16:15:10

+0

您無法訪問具有int類型索引的映射。 – knivil 2011-02-15 16:18:46

回答

1

當您使用手冊循環,它沒有太大的區別。但是,當您使用STL功能(例如來自<algorithm>的功能)時,您沒有選擇。你必須使用迭代器,因爲STL函數使用迭代器,而不是索引。

例如,如果你想使用std::accumulate計算在vector<int>所有整數的總和,那麼你就這樣做:

int sum = std::accumulate(vints.begin(),vints.end(),0); 

所以我的建議是:讓使用迭代器的習慣,如它給你的一致性,也逐漸讓你對迭代器的哲學感到舒服。它給人一種通用的感覺!

1

這兩種方法對迭代遍歷向量都能很好地工作。我對迭代器有偏好,因爲我已經看到使用索引完成的糟糕事情 - 主要是使用一個容器的索引訪問不同容器的人。如果第二個容器較小,這將不起作用。

如果你只是想爲每個元素做點什麼,你可以使用BOOST_FOREACH

std::list<int> list_int(/*...*/); 
BOOST_FOREACH(int i, list_int) 
{ 
    // do something with i 
} 
0

這取決於您是否需要在執行循環體時知道元素在其容器中的位置。如果你這樣做,你需要使用第二種形式。如果不是,請使用第一個,因爲它更通用,因此更靈活;您可以將myvec的類型更改爲支持迭代器的任何內容,即使它不支持隨機訪問。

0

從邁爾斯「有效STL」,項目43

「首選算法調用手寫循環」

  • 算法往往更有效率比環程序員產生
  • 編寫循環是更容易出錯
  • 算法代碼更易讀

使用人儘可能經常使用迭代器。

std::for_each(myvec.begin(), myvec.end(), [](const string& s) { 
    /* your code here */ 
}); 
0

我試圖儘可能隱藏我的容器的底層實現。

在你的榜樣

所以,我會用一個typedef,而不是直接引用該向量開始(以後你會明白爲什麼):

typedef std::vector<string> MyStringCollection; 

然後,我嘗試使用盡可能少的依賴結構可能的基礎實施。在這種情況下,我想遍歷容器和容器使用的值,就像這樣:

for(MyStringCollection::iterator it=mycollection.begin(); it!=mycollection.end(); ++it) 
    { 
    // use *it 
    } 

通過的typedef您的收藏的用戶只需要使用MyStringCollection::iterator,而無需知道什麼MyStringCollection實際上是。

請注意,在C++ 0x中,您可以使用auto,它甚至更短(使我的參數與typedef相關性更低)。

這樣做的好處是,現在變得很容易將MyStringCollection從std :: vector更改爲std :: list。如果因爲性能原因你決定,名單會更適合,你只需要:

  • 從變化的std ::向量typedef的到std ::列表
  • 快速瀏覽一下到所有的地方在哪裏使用MyStringCollection(這將更容易找到比查找所有使用std :: vector