2014-09-19 44 views
6

設A爲std::vector<double>,end()迭代器上的指針運算

這是明確的嗎?

if(!A.empty()) 
    std::vector<double>::iterator myBack = A.end() - 1; 

是在end迭代器只對等式和不等式檢查好?或者只要我留在容器中,我可以執行一些指針算術?

在我的平臺上,此代碼工作。我想知道這是否便攜。

+3

這很好,你也可以使用'A.rbegin()'。 – perreal 2014-09-19 07:28:36

+3

它是* iterator *算術。它應該可以用於雙向迭代器(如'std :: vector :: iterator')。 – Jarod42 2014-09-19 07:28:55

回答

5

這是完全有效的,因爲vector::iterator是一個隨機訪問迭代器。您可以對其執行算術運算,並且不依賴於平臺。

std::vector<double>::iterator it = A.end(); 
while (it != A.begin()){ 
    --it; //this will skip A.end() and loop will break after processing A.front() 
    //do something with 'it' 
} 

A.end()但是指理論過去最端部元件,因此它不指向一個元素,因此不應被解除引用。所以最好的做法是使用反向迭代器,而不是遞減結束迭代器。

for(std::vector<double>::reverse_iterator it = A.rbegin(); it != A.rend(); ++it) { 
    //do something with 'it' 
} 

這兩個循環做同樣的事情,第二就是可以理解的,更清潔的方式來做到這一點。

+0

這兩個循環不相同,第一個循環不會遍歷'A.front()'。 – Jarod42 2014-09-19 07:48:57

+1

但我不認爲'A.begin() - 1'是有效的。 – Jarod42 2014-09-19 08:00:18

4

幾乎安全的,如果你留意的一些特殊情況:

A.end()給你一個迭代器表示位置剛好超過std::vector結束。您應該而不是試圖取消引用它。

如果矢量具有零元素,則A.end() - 1而不是明確定義的。在所有其他情況下,只要您處於容器邊界內,就可以確實執行指針運算。請注意,該標準保證std::vector數據是連續的,並且與包含類型的C++數組完全相同。唯一的例外是std::vector<bool>,由於標準規定的緊包裝專業化,其行爲不同。 (注意sizeof(bool)而不是保證有一個標準的特定值)。

如果我是你,我會使用A.rbegin()訪問最右邊的元素並在繼續之前檢查返回值並堅持迭代器公式。忘記std::vector<bool>專業化非常容易。

+0

我不確定'bool'的情況。這個迭代器 - 不是指針 - 算術,就像@ Jarod42指出的那樣?難道這不應該使它完全安全並且爲'std :: vector '定義好嗎? – 2014-09-19 07:40:49

+0

如果一個'std :: vector '有3個元素,那麼我不相信如果sizeof(bool)== sizeof(int)'定義了'A.end() - 1'。但我可能是錯的。但是如果你把任何東西都扔到'布爾*'上,那你肯定會遇到麻煩。也許'bool'反向迭代器的一個重載運算符負責處理這個問題。簡答:我不知道。我正在考慮在這個問題上給予獎勵。 – Bathsheba 2014-09-19 07:41:44

+0

如果'std :: vector :: iterator'表現得像你說的那樣,對向量的簡單迭代就不起作用。只要你在迭代器上操作,' - 1'必須將它移動一個邏輯元素,而不是'sizeof(bool)'字節。我在http://ideone.com/2pAiE1上添加了一些代碼,只要減法的結果在容器中,它就可以工作。你應該用'_GLIBCXX_DEBUG'(或者編譯器的等價物)對它進行編譯,當你超越邊界時,它會對你咆哮。 – 2014-09-19 07:48:21