STL高效編程(二)- 注意容器的不同特點,小心容器無關的代碼

來源:互聯網
上載者:User

 

STL是建立在泛型之上的。數組泛型為容器,以物件類型為參數。函數泛型成演算法,以迭代器類型為參數。指標泛型為迭代器,參數化了所指向的對象的類型。

 

這隻是個開始。獨立的容器類型泛化為序列或關聯容器,而且類似的容器擁有類似的功能。標準的以連續記憶體為實現的容器都提供隨機訪問迭代器,標準的基於節點的容器都提供雙向迭代器。序列容器支援push_front或push_back,但關聯容器不支援。關聯容器提供對數時間複雜度的lower_bound、upper_bound和equal_range成員函數,但序列容器卻沒有。

 

明白容器的不同特性,對STL編程很重要,因此,寫容器無關的代碼是很危險的。儘管STL提供了很多一致的介面和迭代器類型。

 

最熱心的“容器無關代碼”的鼓吹者很快發現,寫既要和序列容器又要和關聯容器一起工作的代碼並沒有什麼意義。很多成員函數只存在於其中一類容器中,比如,只有序列容器支援push_front或push_back,只有關聯容器支援count和lower_bound,等等。在不同種類中,甚至連一些如insert和erase這樣簡單的操作在名稱和語義上也是天差地別的。舉個例子,當你把一個對象插入一個序列容器中,它保留在你放置的位置。但如果你把一個對象插入到一個關聯容器中,容器會按照的排列順序把這個對象移到它應該在的位置。舉另一個例子,在一個序列容器上用一個迭代器作為參數調用erase,會返回一個新迭代器,但在關聯容器上什麼都不返回。

 

假設, 你希望寫一段可以用在所有常用的序列容器上——vector, deque和list——的代碼。很顯然,你必須使用它們介面的交集來編寫,這意味著不能使用reserve或capacity,因為deque和list不支援它們。由於list的存在意味著你得放棄operator[],而且你必須受限於雙向迭代器的效能。這意味著你不能使用需要隨機訪問迭代器的演算法,包括sort,stable_sort,partial_sort和nth_element

 

另一方面,你渴望支援vector的規則,不使用push_front和pop_front,而且用vector和deque都會使splice和成員函數方式的sort失敗。在上面約束的聯合下,後者意味著你不能在你的“泛化的序列容器”上調用任何一種sort。

 

這是顯而易見的。如果你冒犯裡其中任何一條限制,你的代碼會在至少一個你想要使用的容器配合時發生編譯錯誤。可見這種代碼有多陰險。

這裡的罪魁禍首是不同的序列容器所對應的不同的迭代器、指標和引用的失效規則。要寫能正確地和vector, deque和list配合的代碼,你必須假設任何使那些容器的迭代器,指標或引用失效的操作符真的在你用的容器上起作用了。因此,你必須假設每次調用insert都使所有東西失效了,因為deque::insert會使所有迭代器失效,而且因為缺少capacity,vector::insert也必須假設使所有指標和引用失效。(條款1解釋了deque是唯一一個在迭代器失效的情況下指標和引用仍然有效東西)類似的理由可以推出一個結論,所有對erase的調用必須假設使所有東西失效。

 

 

更多內容,請參見effective STL.

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.