2014-09-19 59 views
1

我正在寫一個測試程序,並發現一個非常有趣的案例std::list的行爲。std :: list是一個循環列表!等等,什麼?

#include <list> 
#include <algorithm> 
#include <iostream> 

int main() 
{ 
    std::list<int> mylist; 
    std::list<int>::iterator iter; 
    for(int i=3; i<10; ++i){ 
     mylist.push_back(i); 
    } 
    iter = mylist.begin(); 
    iter--; 
    iter--; 
    std::cout<<*iter<< std::endl; 
    std::cout<<std::distance(mylist.end(), mylist.begin())<<std::endl; 
} 

輸出是:

9 
1 

如果我沒有記錯的話,這種行爲是有關循環清單。我從未見過論壇,書籍或討論,其中提到標準列表是一個循環列表。我的GCC版本是4.1.2。 那我正確嗎?是標準的std::list一個循環列表?

回答

14

不,std::list不是循環的。當你遞減迭代器時,你的代碼有未定義的行爲。當您致電std::distance(mylist.end(), mylist.begin())時,它也有未定義的行爲,因爲mylist.begin()無法通過遞增mylist.end()到達。

請注意,當您調用未定義的行爲時,std::list看起來可能是循環的,因爲「std :: list似乎是循環的」適合行爲未定義時的允許行爲範圍。這個範圍是任何行爲。

+0

以及爲什麼結束和開始之間的距離是1? – 2014-09-19 11:04:30

+2

@EduardRostomyan:您對'std :: distance'的調用也是未定義的行爲。 – 2014-09-19 11:05:18

+0

如何確定?因爲當我在這種情況下計算向量的距離時,該函數返回一個負數。 – 2014-09-19 11:07:09

2

即使它是循環的在這個實現中你不必依賴它,因爲這個屬性不是標準保證的。 另外您的遞減開始指針是未定義行爲以及std::distance調用。

確實可能列表來實現,可能有你觀察到的結果通過以下方式:

list 
    head --> listelem1 (or elEnd) 
    begin() return head; 
    end() return head->prev; 

listelem1   listelem2   listelem3   elEnd    
    ptr = d1   ptr = d2   ptr = d3   ptr = nullptr 
    next = le2   next = le3   next = elEnd  next = le1 
    prev = elEnd  prev = le1   prev = le2   prev = le3 

但是,這是到庫的實現者,只要他遵循標準的接口和行爲要求。

相關問題