2010-03-31 84 views
3
list<int> foo; 
list<int> foo2; 
list<int>::iterator foo_end = foo.end(); 
list<int>::iterator foo2_end = foo2.end(); 

for (list<int>::iterator it = foo.begin(); it != foo2_end; ++foo) <- notice != comparison here 
{ 
    ... 

它這可以嗎?它會正常工作。比較兩端()迭代器

我傾向於認爲這是實現相關的,任何人都知道,如果標準說這事?

回答

7

有關於此的一個缺陷(LWG defect 446)。缺陷報告詢問是否有效比較引用不同容器元素的迭代器。

缺陷報告中的註釋說明它確實是這樣做的意圖是未定義的,但沒有明確說明它是未定義的。

,擬議的決議中加入以下的標準,明確指出它是未定義:

直接或間接評估任何比較函數或二進制結果 - 有兩個迭代值作爲參數操作從兩個不同的範圍r1和r2(包括它們的過去結束值)獲得的不是一個共同範圍的子範圍是未定義的,除非另有明確說明。

編輯:該語言不包含在C++ 0x FCD中。這個問題實際上是通過N3066中的更改解決的; (§24.2.5/ 2):

前向迭代器的==的域是在同一個基礎序列上的迭代器的域。

2

它是允許(即將編譯)。
它將無法正常工作。

foo2_end點的foo2,不foo結束,所以當它到達的foo2結束,這將是永遠的,因爲你迭代foo你的迭代器將在foo和結束時開始啓動。一旦it迭代到foo的末尾,您將收到seg-fault。

注:我認爲你的意思是寫++it而不是++foo

1

它會編譯但會導致seg錯誤。迭代器是特定於對象的,並且比較來自不同對象的兩個迭代器總是會產生不等式。因此,it != foo2_end表達式將始終評估爲true,並且當it達到foo.end()並且您試圖對其進行解引用時,程序將崩潰。

+0

這取決於迭代器的實現。一個簡單而不是很好的實現一個列表迭代器可能是一個指向該節點的指針,其中null指向一個末尾(這是一個常見的習慣用法)[可能是某個操作需要一個指向列表的指針],相等被定義爲所引用的節點地址的直接比較。標準中沒有任何內容會導致實施不合規。 – 2010-03-31 08:20:13

+0

夠公平的,儘管我認爲商業級編譯器會更聰明些。畢竟,使接口易於正確使用和難以正確使用是一個很好的共同目標。 :) – 2010-03-31 14:47:14

+0

@DavidRodríguez-dribeas「(一個)列表迭代器的實現可能是一個指向節點的指針,空指定一個結尾(這是一個常見的習慣用法)」你能否引用一個這樣的std :: list實施? – curiousguy 2011-09-29 21:15:13