天天看點

Effective STL筆記

#estl 第50條:熟悉與stl相關的web站點。三個:www.sgi.com/tech/stl、www.stlport.org 和 www.boost.org。

#estl 第49條:學會分析與stl相關的編譯器診斷資訊。嗯,第一招是替換大法,然後介紹了一下與容器、插入疊代器、綁定器、輸出疊代器或算法相關的錯誤大概有什麼套路看。

#estl 第48條:總是包含(#include)正确 的頭檔案。因為c++标準沒有規定頭檔案的互相包含關系,是以不同的stl實作有所不同。要記住容器基本上聲明在同名檔案中,算法是algo..和 num..,疊代器在iterator中,函數子和配接器在functional中。

#estl 第47條:避免産生“直寫型”(write-only)的代碼。即所謂容易編寫,但難以閱讀和了解的代碼,比如一行調用函數12次,其中 10 個是互不相同的。

#estl 第46條:考慮使用函數對象而不是函數作為stl算法的參數。嗯,因為函數對象更容易讓編譯器樂于内聯,是以速度會快一些。從代碼被編譯器接受的程度而言,它們更加穩定可靠。

#estl 第45條:正确區分count、find、binary_search、lower_bound、upper_bound和equal_range。嗯,這與傳入的區間是否已經排序有關,與你的目的有關,與容器有關,總之複雜,要自己去看這一小節兩次。

googollee 我一直認為這個應該由重載來完成 rt @laiyonghao: #estl 第44條:容器的成員函數優先于同名的算法。原因:速度更快,且與容器結合得更加緊密,更能夠與容器的行為保持一緻。

#estl 第44條:容器的成員函數優先于同名的算法。原因:速度更快,且與容器結合得更加緊密,更能夠與容器的行為保持一緻。

#estl 第43條:算法調用優先于手寫的循環。三個理由:效率更高,更不容易出錯,和更好的可維護性。

#estl 第42條:確定less<t>與operator<t>具有相同的語義。真理總是如此平淡……還能說啥呢?

#estl 第41條:了解ptr_fun、mem_fun和mem_fun_ref的來由。咳,想起當年了解 .* 和 ->* 的時候多麼地頭痛…… 

#estl 第40條:若一個類是函數子,則應使它可配接。因為 stl 的函數配接器要求一些特殊的類型定義,argument_type,result_type...之類。編寫函數子從unary_function或 binary_function繼承是一個不錯的方案。

#estl 第39條:確定判别式是“純函數”。純函數即傳回值僅僅依賴于其參數的函數。估計在這條陰溝裡翻過船的人不少,哈哈哈。

#estl 第38條:遵循按值傳遞的原則來設計函數子類。換句話說就是讓它們小巧,而且單态。這個條款的意義在于為贅重而且多态的函數子帶來的問題提出一個解決方案,pimpl 慣用法。

#estl 第37條:使用accumulate或者for_each進行區間統計,前者的代碼更明了一些,重要的是它們接受的函數子要求不同。

#estl 第36條:了解copy_if算法的正确實作。文中給出了一個正确實作,注意點是不能要求使用的函數子是可配接的,stl 算法都這樣。

#estl 第35條:通過mismatch或lexicographical_compare實作簡單的忽略大小寫的字元串比較。

#estl 第34條:了解哪此算法要求使用排序的區間作為參數。嗯,stl 算法有不少是要排序的區間的,如果實參并非如此,輕則性能下降,重則邏輯錯誤,不可不察。

#estl 第33條:對包含指針的容器使用remove這一類算法時要特别小心。作為cpp程式員,一定要時刻警惕資源洩漏。boost::shared_ptr是一個好選擇。

#estl 第32條:如果确實需要删除元素,則需要在remove這一類算法之後調用erase。嗯,講的就是erase-remove慣用法的由來,另外在講了一次不同容器删除元素的方法是不同的。

#estl 第31條:了解各種與排序有關的選擇。簡言之,介紹了partition/stable_partition/nth_element /partial_sort/sort/stable_sort的用法和适用場合。

吼吼,到這裡,書就看了一半了。接下來是重頭戲:算法。 #estl 第30條:確定目标區間足夠大。特别是做覆寫的時候,一定要注意,可以先用resize撐大。插入時用back_inserter、front_...、 inserter和ostream_iterator。

#estl 第29條:對于逐個字元的輸入請考慮使用istreambuf_iterator。先說了一下istream_iterator會跳過空白符的問題,然後引入...buf...,後者的性能也會更好,嗯,例子裡的string使用了區間構造函數,又一個推薦的慣用法。

#estl 第28條:正确了解由reverse_itrator的base()成員函數所産生的iterator用法。簡言之就是base()傳回的疊代器有偏移,插入和删除操作的時候要注意。再介紹了一個v.erase((++ri).base())慣用法。

#estl 第27條:使用distance和advance将容器的const_iterator轉換成iterator。其實這是前一條的延伸,講述了相應的轉換方法和要注意的地方,比如顯式指定distance的類型參數為const_...,以避免編譯器推斷。

周末在家繼續看了一點點書,補推上來。 #estl 第26條:iterator優先于const_iterator、reverse_...以及const_reverse...。因為 insert/erase等函數需要,以及彼此間的比較,還有就是iterator更能靈活轉換。

=============== 一半的分割線 ==================

#estl 第25條:熟悉非标準的哈希容器。嗯,這些玩意兒是非标準的,c++0x 出來以後就會有标準了……

rt @googollee: 用vector的好處是記憶體布局可控,可直接導給c api。應該是vector性能不行了才用關聯容器 rt @laiyonghao  #estl  第23條:考慮用排序的vector替代關聯容器。……//維護一個sorted_vector代價挺大的。

#estl 第24條:當效率至關重要時,請在map::operator[]與map::insert之間謹慎做出選擇。簡言之,增加時使用insert,更新時使用[]。

#estl 第23條:考慮用排序的vector替代關聯容器。額,我覺得除非證明了關聯容器性能不行了,不然不應該考慮。map 不行了用 hashmap。

#estl 第22條:切勿直接修改set或multiset中的鍵。關鍵是要記住如果直接修改了,那麼要保證該容器仍然是排序的。對python之類的語言其實也是如此。

 #estl 第21條:總是讓比較函數在等值情況下傳回false。聽起來像廢話?嗯,重要的是要記得 !(a<b) 的意思是 a>=b,切記要把前者寫成 b<a 形式。  回複  回推

#estl 第20條:為包含指針的關聯容器指定比較類型。這條已經約定成俗了,沒什麼好說的。

#estl 第19條:了解相等(equality)和等價(equivalence)的差別。相等,以 operator== 為基礎,等價,以 operator< 為基礎,當 !(a<b)&&!(b<a) 時兩者等價。

#estl 讀完第2章,再感歎一下溫故知新。另外 twitter 真是做讀書筆記的好工具。

#estl 第18條:避免使用vector<bool>。這條也是金規玉律了,無需多言。

#estl 第17條:使用“swap技巧”去除多餘的容量。這條太常用了,沒啥好說的。 

#estl 第16條:了解如何把 vector和string資料傳給舊的api。嗯,再一次覺得&v[0]實在太惡心了。因為隻有vector才保證和數組有同樣的記憶體布局,是以如果要把map之類的容器内容傳給c-api,可能需要vector中轉一下。

#estl 第15條:注意string實作的多樣性。談到了四個不同的實作,并分析了他們占用的記憶體大小,引用和共享能力。非常有趣。

#estl 第14條:使用reserve來避免不必要的重新配置設定。先分析了vector/string的記憶體政策和相關的方法,然後談到reserve慣用法。

#estl 第13條:vector和string優先于動态配置設定的數組。主要因為它們的記憶體管理和各種嵌套類型定義友善程式設計,另外讨論到基于引用計數的string 可能在多線程環境中損失性能。

重看 #estl 已經看完第一章了,我不得不說 c++ 的書是會中毒的,我現在變得有很強的欲望去重看 ecpp 和 mecpp 了……我好不容易通過寫py三年修來的金身馬上要破了……

#estl 第12條:切勿對stl容器的線程安全性有不切實際的依賴。隻能期望(不可依賴哦)多線程讀是安全的,多個線程對不同的容器做寫入操作是安全的。

#estl 又讀了一遍第10條。第11條:了解自定義配置設定子的合理用法。

#estl 第10條:了解配置設定子(allocator)的約定和限制。果然溫故知新,這一條耗了我好幾個編譯代碼的時間……可能仍然需要再重讀幾遍,鵝米豆腐……

#estl 第8條:切勿建立包含auto_ptr的容器對象;第9條:慎重選擇删除元素的方法。關鍵點:auto_ptr在拷貝時轉移所有權;序列容器和關聯容器的删除方法不一樣,list尤其特别。

rt @googollee: 第7條看情況吧,如果容器裡的東西在容器銷毀後還需要繼續存在的話就不能delete。ecpp是embedded cpp麼? rt @laiyonghao: #ecpp  第7條…… // 我用錯tag了,effective stl,以後改 #estl

#ecpp 第7條:如果容器中包含了通過new操作建立的指針,切記在容器對象析構前将指針delete掉;第8條:切勿建立包含auto_ptr的容器對象。

#ecpp 第6條:當心c++編譯器最煩人的分析機制。意思大概是在函數調用時避免使用匿名對象作實參,以消除對編譯器的二義性。

#ecpp 第5條:區間成員函數優先于與之對應的單元素成員函數。區間成員函數寫起來更容易,更能清楚地表達你的意圖,而且它們表現出了更高的效率。

#ecpp 第3條:確定容器中的對象拷貝正确而高效;第4條:調用 empty 而不是檢查 size() 是否為 0。

重讀《effective stl 中文版》。第1條:慎重選擇容器類型;第2條:不要試圖編寫獨立于容器類型的代碼。

繼續閱讀