鉅細靡遺 井然有序

《C++ 標準程式庫》侯捷譯序

the-cpp-standard-library-c.jpg (10735 bytes)


自從1998C++ Standard定案以後,C++ 程式庫便有了大幅擴充。原先為大家所熟知、標準規格定案前蘊釀已久的STLStandard Template Library,標準模板程式庫),不再被單獨對待,而是被納入整個C++ 標準程式庫(Standard Library)。同時,原有的程式庫(如iostream)也根據泛型技術(generics)在內部上做了很大的修改。可以說,C++ Standard的發佈對C++ 社群帶來了翻天覆地的大變動 —  不是來自語言本身,而是來自標準程式庫。這個變動,影響C++ 程式編寫風格至鉅,C++之父Bjarne Stroustrup並因此寫了一篇文章:Learning Standard C++ as a New Language(載於C/C++ User's Journal, 1999/05)。

我個人於1998年開始潛心研究泛型技術和STL,本書英文版《The C++ Standard Library》甫一出版便成為我學習C++ 標準程式庫的最重要案頭工具之一。小有心得之後,我寫過數篇相關技術文章,從來離不開本書的影響和幫助。我曾經把STL(代表泛型技術目前最被廣泛運用的一個成熟產品,也是C++ 標準程式庫的絕大成份)的學習比喻為三個階段(或層次):

  • 第一境界:熟用STL
  • 第二境界:瞭解泛型技術的內涵與STL的學理乃至實作
  • 第三境界:擴充STL

不論哪一個階段,你都能夠從本書獲得不同程度的幫助。

第一階段(對最大多數程式員有立竿見影之效),我們需要一本全面而詳盡的教本,附帶多量而設計良好的範例,帶領我們認識十數個STL容器(containers)、數十個STL演算法(algorithms)、許許多多的迭代器(iteartors)、配接器(adapters)、仿函式(functors)…的各種特性和用途。這些為數繁多的組件必須經過良好的編排組織和索引,才能成就一本效果良好、富教育性又可供長久查閱的案頭工具書。

在這一階段裡,本書表現極為優異。書中運用許多圖表,對所有STL組件的成員做了極其詳盡的整理。更值得稱道的是書中交叉參考(cross reference)做得非常好,在許多關鍵地點告訴讀者當下可參見哪一章哪一節哪一頁,對於閱讀和學習帶來很大的幫助(本中文版以頁頁對譯方式保留了所有交叉參考和索引)。

第二階段(從STL的運用晉升至泛型技術的學習),我們需要一些關鍵的STL源碼(或偽碼, pseudo code),幫助我們理解關鍵的資料結構、關鍵的編程技術。認識這些關鍵源碼(或偽碼)同時也有助提昇第一階段的運用深度(學會使用一樣東西,卻不知道它的道理,不高明J 註1)。

本書很多地方都提供了C++ 標準程式庫的關鍵源碼。不全面,但很關鍵。

註1乍見之下令人錯愕的一句話。看電視需要先了解電視的原理嗎?呵呵,話講白就沒意思了。這句話當然是對技術人員說的。

第三階段(成為一位泛型技術專家;打造自己的STL相容組件),我們需要深入了解STL的設計理念和組織架構(註2),並深入(且全面地)了解STL實作手法(註3)。是的,不入虎穴,不能得虎子;徹底了解STL如何被打造出來之後,你才能寫出和STL水乳交融、完美整合的自定組件(user-defined components)。

本書對第三階段的學習也有相當幫助。雖然沒能提供全面的STL源碼並分析其技術(那需要另外800J ),卻提供了為數不少的訂製型組件實作範例:p191, p213提供了一個執行期指定排序準則並運用不同排序準則的實例,p219提供一個自定容器(雖然只是個簡單的包覆類別),p222提供一個「reference語意」示範作法, p285提供一個針對迭代器而設計的泛型演算法,p288提供一個用於關聯式容器的訂製型inserterp294有一個自定的排序準則,p441有一個自定的(安全的)stackp450有一個自定的(安全的)queuep504有一個自定的traits class for string p614有一個自定的stream操控器,p663有一個自定的stream緩衝區,p735有一個自定的記憶體配置器(allocator)。

2這方面我推薦你看《Generic Programming and the STL - Using and Extending the C++ Standard Template Library, by Matthew H. Austern, Addison Wesley 1998。詳見稍後說明。中譯本《泛型程式設計與STL,侯捷/黃俊堯合譯, 眳p, 2001

3這方面我推薦你看《STL源碼剖析, The Annotated STL Sourcesby 侯捷, 眳p, 2002。詳見稍後說明。

除了眾所矚目的STL,本書也涵蓋一般不被歸類為STLString程式庫,以及一般不被視為關鍵的IOStreamLocale程式庫(註4)。三部分互有關連,以IOStream為主幹。在GUI(圖形使用介面)和application framework(應用程式框架)當道的今天,IOStream提供的輸出輸入可能對大部份人失去了價值,但如果你希望開拓OO技術視野,IOStream是一顆沉睡的珠寶。

4這方面見的專著是《Standard C++ IOStreams and Locales - Advanced Programmer's and Reference, by Angelika Langer and Klaus Kreft, Addison Wesley 2000

v v v

泛型技術不僅在C++ 被發揚光大,在Java上也有發展(註5),在C# 上亦被眾人期待。從目前的勢頭看,泛型技術(Generics)或許是物件導向(Object Oriented)技術以來程式編寫方面的又一個巨大衝擊。新一代C++ 標準程式庫(註6)將採用更多更複雜更具威力的泛型技術,提供給C++ 社群更多更好更具復用價值的組件。

5(1) GJ : A Generic Java, by Philip Wadler, Dr. Dobb's Journal February 2000. (2) JSR- 000014 : Adding Generics to the Java Programming Language,
http://jcp.org/aboutJava/communityprocess/review/jsr014/index.html

6請參考http://www.boost.org/,此物據稱將成為下一代 C++標準。

不論你要不要、想不想、有沒有興趣在你的程式編寫過程中直接用上泛型技術,至少,在C++ 程式編寫過程中你已經不可或缺於泛型技術帶來的成熟產品:C++ 標準程式庫。只要你具備C++ 語言基礎,本書便可以帶領你漂亮地運用C++ 標準程式庫,漂亮地提昇你的編程效率和程式品質。

面對陌生,程式員最大的障礙在於心中的怯弱。To be or not to be, that is the question! 不要像哈姆雷特一樣猶豫不決。面對光明的技術,必須果敢。

v v v

關於術語的處理,本書大致原則如下:

  1. STL各種資料結構名稱皆不譯,例如array, vector, list, deque, hast table, map, set, stack, queue, tree…。雖然其中某些已有約定俗成的中文術語,但另一些沒有既標準又被普遍運用的中文名稱,強譯之讀者瞠目以對,部分譯部分不譯則閱讀時詞性平衡感不佳(例如「面對向量deque兩種容器」就不如「面對vectordeque兩種容器」讀起來順暢)。因此,資料結構名稱全部不譯。直接呈現這些簡短的英文術語,可能營造更突出的視覺效果,反而有利閱讀。技術書籍的翻譯不是為了建立全中文化閱讀環境,我們的讀者水平也不可能受制於這些英文單字。
  2. STL六大組件的英文名稱原打算全部保留,但由於處處出現,對版面的中英文比例形成視覺威脅,因此全部採用以下譯名:container容器algorithm演算法iterator迭代器adapter配接器functor仿函式(註7)allocator配置器
  3. 任何一個被保留的英文關鍵術語,其第一次(或前數次)出現時儘可能帶上中文名稱。同樣地,任何關鍵的中文術語,我也會時而讓它中英並陳。

7原書大部份時候使用function object函式物件一詞,為求精簡及突出,中文版全部改用其另一個名稱functor仿函式(見第8章譯註)。

v v v

關於編排,本書原則如下:

  1. 全書按英文版頁次編排,並因而得以保留原書索引。索引詞條皆不譯。
  2. 中文版採用之程式碼字體(Courier New 8.5)比文本字體(細明體9.5)小,英文版之程式碼字體卻比其文本字體大,且行距寬。因此中文版遇有大篇幅程式列表,為保持和英文版頁次相應,便會出現較多留白。根據我個人對書籍的經驗,去除這些留白的最後結果亦不能為全書節省五頁十頁;填滿每一處空白卻喪失許多立即可享的好處,智者不取J

v v v

一旦你從本書獲得了對C++ 標準程式庫運用層面的全盤掌握與實踐經驗之後,可能希望對STL原理乃至實作技術做更深的研究,或甚至對泛型編程(Generic Programming)產生無比狂熱。在眾多相關書籍之中,下面是我認為非常值得繼續進修的四本書:

  1. Generic Programming and the STL - Using and Extending the C++ Standard Template Library, by Matthew H. Austern, Addison Wesley 1998。本書第一篇(前五章)談論STL的設計哲學、程式庫背後的嚴密架構和嚴謹定義。其中對於STL之異於一般程式庫,有許多重要立論。其餘部分(第二篇、第三篇)是STL的完整規格(分別從concepts的角度和components的角度來闡述),並附範例程式。
  2. STL源碼剖析, The Annotated STL Sources》by 侯捷, 眳p, 2002。本書剖析 STL實作技法,詳實揭示並註解STL六大組件的底層實作,並以公認最嚴謹的SGI(Silicon Graphics Inc.)STL版本為剖析對象。附許多精彩分析圖,對於高度精巧的記憶體配置策略、各種資料結構、各種演算法、乃至極為「不可思議」的配接器(adapter)實作手法,都有深入的剖析。
  3. Effective STL》, by Scott Meyers, Addison Wesley 2001。本書定位為STL的深層運用。在深層運用的過程中,你會遇到一些難解的問題和效率的考量,你需要知道什麼該做、什麼該避免。本書提供50個專家條款。請注意,深層運用和效率調校,可能需要讀者先對底部機制有相當程度的了解。
  4. Modren C++ Design》by Andrei Alexandrescu, Addison Wesley 2001。將泛型技術發揮到淋漓盡致、令人目瞪口獃的一本書籍。企圖將泛型技術和設計樣式(design patterns)結合在一起。領先時代開創先河的一本書。

generic-programming-and-stl.jpg (26611 bytes) tass.jpg (33378 bytes) meyers3.jpg (31544 bytes) modern-cpp-design.jpg (39141 bytes)

v v v

本書由我和孟岩先生共同完成。孟岩在大陸技術論壇以C++/OO/Generics馳名,見解深雋文筆不凡。我很高興和他共同完成這部作品。所謂合譯,我們兩人對全書都有完整的參與(而非你一半我一半的對拆法),最終由我定稿。本書同時發行繁體版和簡體版,基於兩岸計算機術語的岐異性,簡體版由孟岩負責必要轉換。

侯捷 2002/05/23 于新竹

http://www.jjhou.com(繁體網站)
http://jjhou.csdn.net(簡體網站)
jjhou@jjhou.com(個人電子郵箱)