2011-08-31 68 views
4

短的問題之前:是使用下面的代碼不安全的其他編譯器比我(的mingw32),或者是有效使用?的std ::列表<>:元素l.begin()

list<int> l; 
/* add elements */ 
list<int>::iterator i = l.begin(); 
i--; 
i++; 
cout << *i << endl; 

...或者換句話說:是i定義爲指向在此之後l.begin()

回答

12

是,代碼是不安全的。一旦您嘗試移動begin()之前,您已導致未定義的行爲。試圖移動「回來」可能無法正常工作。

+0

是'--list.end()不這樣做'也UB? –

+0

只要列表不爲空,就沒問題。你會在列表中的最後一個「真實」元素。 ++ list.end()將是未定義的。 –

+2

@SethCarnegie:'list.end()'不是一個左值,所以它的格式不正確。當且僅當列表不爲空時,纔可以遞減指向「list.end()」的迭代器。 –

2

一個std ::列表,經由鏈表指針橫穿它的內容,所以指針運算不用於計算正確的位置。 .begin()之前的位置將沒有數據,並且不應提供任何有效的遍歷機制。

容器,如性病::載體具有隨機訪問迭代器,並會在幕後使用指針運算,所以他們可能會給出正確的結果(沒問題),但它仍然是一個壞主意。

因此,它不應該工作,它的不確定,即使它不以某種方式工作:)

+0

鏈接列表和指針是一個完整的實現細節。 –

+0

像std :: vector <>'這樣的容器的迭代器仍然遵循標準中有關雙向+迭代器的規則,它具體地說這是未定義的行爲。 – ildjarn

+0

是的,我同意這兩個評論 - 它的未定義和鏈接列表是一個實現細節。但它可能不適用於他的情況,因爲它幾乎可以肯定是一個鏈表,而biderectional迭代器很可能使用向量的指針運算,所以應該允許運動通過末端。雖然這是違反標準和壞的,但我認爲他們會很好的考慮。如果我添加了一些混淆,應用:( –

相關問題