我一直在使用地圖/矢量廣泛的這些天,但有一個疑問,在迭代他們
迭代矢量/地圖數據結構,C++
哪一個更好?
for(vector<string>::iterator it=myvec.begin(); it!=myvec.end(); ++it){
}
或
for(int i=0; i < myvec.size(); i++){
myvec[i]
}
首先,是他們打算做同樣的事情?
我一直在使用地圖/矢量廣泛的這些天,但有一個疑問,在迭代他們
迭代矢量/地圖數據結構,C++
哪一個更好?
for(vector<string>::iterator it=myvec.begin(); it!=myvec.end(); ++it){
}
或
for(int i=0; i < myvec.size(); i++){
myvec[i]
}
首先,是他們打算做同樣的事情?
當您使用手冊循環,它沒有太大的區別。但是,當您使用STL功能(例如來自<algorithm>
的功能)時,您沒有選擇。你必須使用迭代器,因爲STL函數使用迭代器,而不是索引。
例如,如果你想使用std::accumulate
計算在vector<int>
所有整數的總和,那麼你就這樣做:
int sum = std::accumulate(vints.begin(),vints.end(),0);
所以我的建議是:讓使用迭代器的習慣,如它給你的一致性,也逐漸讓你對迭代器的哲學感到舒服。它給人一種通用的感覺!
這兩種方法對迭代遍歷向量都能很好地工作。我對迭代器有偏好,因爲我已經看到使用索引完成的糟糕事情 - 主要是使用一個容器的索引訪問不同容器的人。如果第二個容器較小,這將不起作用。
如果你只是想爲每個元素做點什麼,你可以使用BOOST_FOREACH。
std::list<int> list_int(/*...*/);
BOOST_FOREACH(int i, list_int)
{
// do something with i
}
這取決於您是否需要在執行循環體時知道元素在其容器中的位置。如果你這樣做,你需要使用第二種形式。如果不是,請使用第一個,因爲它更通用,因此更靈活;您可以將myvec
的類型更改爲支持迭代器的任何內容,即使它不支持隨機訪問。
從邁爾斯「有效STL」,項目43
「首選算法調用手寫循環」
使用人儘可能經常使用迭代器。
std::for_each(myvec.begin(), myvec.end(), [](const string& s) {
/* your code here */
});
我試圖儘可能隱藏我的容器的底層實現。
在你的榜樣所以,我會用一個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。如果因爲性能原因你決定,名單會更適合,你只需要:
更好的是什麼?你想訪問你的容器的元素? – knivil 2011-02-15 16:12:48
我只想訪問元素以任何順序 – rda3mon 2011-02-15 16:15:10
您無法訪問具有int類型索引的映射。 –
knivil
2011-02-15 16:18:46