2010-11-04 146 views
5

只見用來從std::vector刪除一個選擇的元素下面的代碼:迭代器是否支持+運算符?

vector<hgCoord>::iterator it; 
int iIndex = 0; 
    const int iSelected = 5; 
for(it = vecPoints.begin(); it != vecPoints.end(); ++it, ++iIndex) 
{ 
    if(iIndex == iSelected) 
    { 
     vecPoints.erase(it); 
     break; 
    } 
} 

我認爲,這個代碼是沒有效率的,應該按如下方式寫入:

vector<hgCoord>::iterator it; 
int iIndex = 0; 
    const int iSelected = 5; // we assume the vector has more than 5 elements. 

    vecPoints.erase(vecPoints.begin() + iSelected); 

不過,我不是確定此代碼是否遵循C++ STL標準。

+0

你是對的,因爲'std :: vector :: iterator'是一個'RandomAccessIterator'(又名'T *')。請記住,如果向量中的元素少於5個,則第二個算法將失敗。 – 2010-11-04 19:12:53

+1

如果這些前綴''i'是匈牙利符號的一種形式,我強烈反對任何一段代碼。 – 2010-11-04 19:30:13

+0

@ eq-:什麼,因爲'i'應該用作'iterator'的前綴,你的意思是;-p – 2010-11-04 19:54:13

回答

12

爲了使代碼通用的,所以它的作品無論是否迭代器支持operator +,並使用最有效的可用的執行:

template <typename C> 
void erase_at(C& container, typename C::size_type index) { 
    typename C::iterator i = container.begin(); 
    std::advance(i, index); 
    container.erase(i); 
} 

內部,std::advance使用operator +如果迭代器類型支持它。否則(例如,對於std::list<>::iterator),它將循環中的迭代器逐步推進一步,就像您發佈的第一個代碼一樣。

+0

......... yup ..... +1 – 2010-11-04 19:41:54

+3

回覆對dirbeas'已刪除答案的評論 - 我認爲'std :: advance'修改其參數的原因與事實有關因爲它非常不依賴於類型,特別是它適用於所有的InputIterator,它們是*便宜*但*危險*拷貝。當與可能只是InputIterator的迭代器(不是ForwardIterator)一起使用時,不能再安全地使用舊值,因此即使它返回了迭代器,仍然只能將它用作'i = std ::提前(i,n);',或者像在dribeas'代碼中一樣臨時。返回'無效'有助於防止愚蠢。有時。也許。 – 2010-11-04 19:49:06

+0

謝謝你的解釋。 – q0987 2010-11-04 21:17:14

10

隨機訪問迭代器支持加法和減法,並且std::vector迭代器是隨機訪問。

2

你正確地認爲:)

1

這應該工作的優良載體,因爲向量迭代器是隨機訪問迭代器,所以沒關係添加爲你所做的偏移量。對於其他一些容器類型(如deque或map)也是如此。

因此,你的代碼對於一個向量更好,但其他代碼可能已經打算與其他類型的容器一起工作。

+0

實際上,'deque'也使用隨機訪問迭代器。 – 2010-11-04 19:56:38

+0

我認爲修改過的代碼適用於vector,string和deque。 – q0987 2010-11-04 21:16:46

+0

@Fred Larson:哎呀!我不知道我爲什麼輸入deque,我的意思是列表!感謝您的更正。 – dajames 2010-11-16 13:41:26