天天看點

【Scott Meyers】C++5×5斷想之二:C++曆史上最重要的文獻作者介紹

原文位址:http://www.artima.com/cppsource/top_cpp_publications.html。譯文發表于《程式員》2006.12。

作者介紹

【Scott Meyers】C++5×5斷想之二:C++曆史上最重要的文獻作者介紹

Scott Meyers,C++頂級權威之一,為世界各地客戶提供教育訓練和咨詢服務。出版有暢銷的Effective C++系列圖書(《Effective C++》、《More Effective C++》和《Effective STL》),設計了創新型的Effective C++ CD,Addison Wesley的Effective Software Development Series顧問編輯,The C++ Source (http://www.artima.com/cppsource/)咨詢闆塊專家。布朗大學計算機科學博士,他的網站是www.aristeia.com。

在本系列的上一篇文章裡,我列出了我認為最重要的五本C++圖書,但大量有關C++的重要文獻并非來自圖書。比如期刊、雜志、網絡上的文章;博士論文、會議紀要;新聞討論區文章;部落格;标準化文檔等很多很多。它們對C++的進步與繁榮作出了巨大貢獻。我沒有讀全,甚至談不上讀了大多數,但作為C++的長期關注者,我還是閱讀了很多這類文獻。在本期裡,我将評選C++曆史上最重要的五部非圖書類文獻。和上期評選圖書一樣,我仍然将數量限制為五,盡管我沒有寫出過重要到能上這個榜的東西,但仍然将自己列入了候選隊伍。以下文獻按時間為序。

一個讓我無可回避的邏輯範疇兩難問題是:如果文獻A的思想對C++直接影響很小,但文獻B的作者讀到了A,将這個思想引入了B并産生了巨大影響,那麼到底哪個文獻更重要,A(“發明者”)還是B(“繁榮者”)?我最終選擇了B,并不是因為這種做法天然就正确,而是因為我不想花力氣拼命追查下列文獻作者的思想是否從别的文獻繼承而來[注釋1]。反過來,我随便翻到C++語言規範的某頁。大家知道,const member functions裡的const是不徹底的:指針資料成員自動變為const,但指針所指的資料本身不會。借鑒這個規定,我假設公布在下面的名單裡的文獻重要,而忽略它們引用的基礎物(以及我所不知的其他文獻)。當然,從C++本身來說,這可能不是正确的做法,但易于實作,是以我也這麼幹了[注釋2]。

在詳細解說名單之前,我想請各位發發善心,允許我為《C++ Report》——曾經為C++作出了最重大貢獻的期刊——說幾句悼詞(如果你不那麼仁慈,就請直接跳過去閱讀後面内容吧)。在其存在的大部分時期(1989-2000)裡,《C++ Report》一直是C++推動者和鼓吹者紙張寫作的樂園(在此期間,首倡電子寫作的是Usenet新聞討論區comp.lang.c++,後來還有comp.std.c++和comp.lang.c++.moderated)。在《C++ Report》發表文章的人裡,有些名字你可能聽說過(比如我上期列出的“最重要的C++圖書”的作者),更多的可能你就不知道了(譬如下面要提到的一些文獻的作者,以及——算了,名單太長,簡直沒辦法開始。我知道,如果開了頭列出一些名字,那就暗示着未列出的人沒列出的那麼重要,這樣一來我的麻煩就大了。是以幹脆一個不提,但請相信我,《C++ Report》有生之年一直相當興盛,它吸引了這個領域最好的寫作群體——都是最有興趣,也是最有實力去寫作的人)。《C++ Report》關門的時候,很多專欄作家投向了《C/C++ Users Journal》,但這個雜志從來沒有像《C++ Report》那樣吸引過我;現在,CUJ也停刊了。《C++ Report》留給像我這樣整天胡說八道的老怪物們的,就隻有面對時光飛逝的無奈哀歎了。

唠叨這麼多,我感覺好點了,還是繼續說我的最重要非圖書類文獻名單吧:

《Programming in C++, Rules and Recommendations》,作者是Ellemtel電信系統實驗室的Mats Henricson和Erik Nyquist,1992年。在我90年代早期前後的一些文章裡,我提到過當時很多程式員渴求如何駕馭C++威力方面的指導意見,他們最感興趣的是告訴他們該做什麼、不該做什麼的程式設計引導手冊。幾乎在我的《Effective C++》嘗試提供這方面指導的同時,Mats Henricson和Erik Nyquist在網際網路上釋出了他們寫的程式設計手冊。其實在此之前,這本手冊就出來一段時間了,但因為是瑞典文,是以大大限制了它的傳播。

Ellemtel版手冊以技術性語言寫成,容易閱讀,是以二位作者聲名遠播、影響很大。不久,大家得知他們準備成書出版,此時我就有不祥預感(競争于市場可能是件好事,但那時,我是這個市場上僅有的參與者。我真的很喜歡這本書冊的風格[注釋3])。我們對這本書滿懷期待,轉眼間時間過去了幾年。1996年底,它終于面世了(《Industrial Strength C++》,Mats Henricson和Erik Nyquist, Prentice Hall, 1997),但那個時候,這本書的很多指導意見與同時代的編譯器相比已經過時,它包含的很多資訊在C++社群裡已經廣為人知,與4年前第一次的英文版相比,人們感覺它的作用已經大打折扣。我閱讀了這本書,先是興趣滿懷,然後就有點傷感,因為我感覺到花費4年時光從網際網路文檔到成書,不僅它包含的技術資訊失去了當年的光芒,寫作本身也喪失了原有的精神。我估計原稿已經被無數次修改,以期符合評審者在各方面的要求。這就解釋了它為什麼花費了如此長時間才得以出版,為什麼最後的成書如此平淡。

我想,作者和出版商對這本書寄予厚望,但事與願違,不過這并不能削弱最初網際網路版本的影響力。它一出來,C++程式員就一口咬了上去。它是C++最佳實踐規範總結道路上的重要裡程碑。

《Exception Handling: A False Sense of Security》,作者Tom Cargill,1994年發表于《C++ Report》11、12月刊。1994年,C++社群矯矜之氣彌漫。當時,C++是很熱門的語言,工作崗位充足,很多人認為C++無所不能。在此前幾年裡,這門語言裡增加很多重要的特性,比如多繼承、模闆,以及稍晚點的異常。因為異常是新事物,《C++ Report》上就出現了很多讨論文章,凡是C++程式員出現的場合,大家都是三句話不離異常。很多文章反映了屬于那個時代的狂熱:“異常美妙之極,它們讓錯誤處理變得簡單。你需要做的所有事情就是去了解try、throw和catch。看我編寫一個堆棧類吧,告訴你們C++有了異常處理後,将比過去酷多少。” Tom Cargill的文章(是他的長期專欄“C++ Gadfly”——這是多年來最名副其實的專欄之一——裡的一篇)拂去了我們臉上集體自滿的微笑。僅僅用一句話,Cargill就說明了try、throw和catch對這個問題毫無幫助:

運用異常的真正難點在于如何以如下方式編寫所有介于二者(thow和catch)之間的代碼:任何異常都能從throw處安全到達處理它的地方,且不破壞傳遞路線上的其他程式部分。

這個專欄繼續剖析了《C++ Report》上我剛才提到過的“異常美妙之極”系列專欄上的文章[注釋4],最後以一個擂台(Cargill稱之為“邀請”)結束:釋出一個異常安全的堆棧類。這個挑戰引來了潮水般的回應,但我認為,直到1997年,Herb Sutter發表的一篇文章才算真正有分量(後面會說到這個事情)。

我認為Tom Cargill的專欄文章不僅證明了我們對于異常想法的幼稚,而且也還了C++一個清白。在我們明白如何編寫異常安全的代碼時,Java這門可愛的新語言出現了(就我所知,現在是Ruby on Rails),曾經信誓旦旦的“我們天下第一”狂想再也沒有回來過。

《Curiously Recurring Template Patterns》,Jim Coplien于1995年發表在《C++ Report》2月刊。這篇文章的意義不在于它的内容本身,而在于它給所述内容的命名。真是雙重巧合啊,這篇文章來自于Coplien的專欄“The Column Without a Name”,而且他給文章起的名字也已經直接成了一個模式名:The Curiously Recurring Template Pattern (CRTP)[注釋5]。這個模式本身是指将派生類作為參數在它自己的模闆化基類裡使用:

template<typename T>

class Base { ... };

class Derived: public Base<Derived>

{ ... };

很多人對模闆的使用都超出了T容器的範圍,最後往往皈依到了CRTP的設計思想。這時候,他們通常都會懷疑這樣的代碼是否可以通過編譯,當發現可以通過編譯(可能他們大吃了一驚)後,就很擔心自己弄出這樣的設計,是否是頭腦癡呆的早期症狀。就在這時,Coplien投稿了。更多有經驗的同僚會保證說:“不是啊,你沒有精神病。從基類派生一個類,基類又在派生類的基礎上模闆化,不僅是合法的設計技術,而且它還有一個正式的名字呢:the Curiously Recurring Template Pattern。”

《Using C++ Template Metaprograms》,作者Todd Veldhuizen,《C++ Report》1995年5月。此文見證了template metaprogramming (TMP)的第一次大規模出現熱潮。這是一個重要的時期,但我完全錯過了這條船。我清楚記得閱讀這篇文章時我的想法:“好,這樣你就可以用遞歸的執行個體化模闆去模拟編譯時的循環。你能通過模闆特化去實作編譯時的switch表達式。太好了!但你為什麼要這樣做?”哦,我說謊了。我當時真正的想法是:“但你如果這樣做,你就是個瘋子。”[注釋6]

盡管C++社群并不缺乏追捧,再後來有關TMP的文章也在各種論壇上陸續出現,不過這不讓我驚詫。我那時深信TMP是一門概念過于離奇、文法過于超前以至于沒有立足點的技術。現在,我知道大多數人似乎也同意它在文法上的确讓人感覺不适,概念上不說過于怪異,至少也偏離了主流思想,這讓我得到了些許安慰。但很清楚,它獲得的支援日益增多,已經成為每個庫程式員技巧包裡的重要工具。為了彌補Veldhuizen首次描述它時我對其重要性嚴重低估的過失,我在《Effective C++》第三版的一個條款裡盡我全力總結了這門技術及其用途。

《Exception-Safety in Generic Components》,作者David Abrahams。我能找到的最早的是發表在德國《Dagstuhl Castle》1998年4月27日到5月1日的《Proceedings of the International Seminar on Generic Programming》。不過我想在1997年中,相關文獻可能就出現了,因為Herb Sutter發表在《C++ Report》(也許是别的雜志)1997年9月刊的一篇文章引用了David Abrahams論文裡的内容。我也發現有對David Abrahams于1997年4月發表在Usenet上的文章(http://tinyurl.com/nk5vn)裡内容的引用,不幸的是,這個連結已經實效。

現在,保證函數提供基本、強健和無抛出的三個異常安全辦法已經廣為人知。Herb Sutter傳播了這些術語,并且寫了很多相關的文章,但最早提出它們的是David Abrahams,我這麼說的主要理由是Sutter已經很細心地承認過這一點[注釋7]。一些重要文獻初生于相當狹小的空間,但讀者中間很多人有條件發揮廣泛影響力(比如正在定義C++标準,或者負責标準庫的實作),是以文獻的影響力将會被大大提高。我想,這就是一個例子。

有趣的是,盡管Abrahams的文獻啟蒙了我們對奠定C++标準庫規範基礎的異常安全的了解,但C++标準裡卻未提及“basic guarantee”、“strong guarantee”或是“nothrow guarantee”。

注釋:

1.因為傳遞環路問題(比如B的想法起源于A,但A的靈感來自于Z,Z又是受Y的影響……),實際情況比這還要糟糕。

        2. const不徹底的這個理由可能和簡化實作并不相幹。其實考察const和指針結合時的常見規則,它就是一個很自然的結果。我們定義指針p為const,但這并不能限定*p也是const。在const member function裡,*this是const,如果p是*this的一個指針成員,我們也不能确定*p就是const。

        3.稍早一點,還有另一本C++書冊類圖書,即Thomas Plum與Dan Saks合著的《C++ Programming Guidelines》,1991年由Plum Hall出版,但它從未引起過大量關注。我很早就讀過這本書,現在我又快速閱讀了一遍,給它的結論是:嗯……相當無趣。

        4.我是《C++ Report》的專欄作家,我記得那時候就在想,Cargill肯定瞄上了我,要我去寫異常方面的東西。系統且有專業眼光地挑出同僚作品中的缺點,是我曾經經曆過的最費心勞神的事情。我确信從此以後,自己不是發表作品前要再三檢查的唯一專欄作家了。

        5.正在布朗大學計算機科學系攻讀博士學位的Andrei Alexandrescu曾經公開指出這個模式的名字應該被還以本色,比如“F-bounded polymorphism”,但很不幸,他的意見沒有引起人們的注意。這件事引起了我的興趣,因為我就在那兒獲得了博士學位,不過我從未聽說過“F-bounded polymorphism”。CRTP盡管是一個古老的名字,但仍然能打動我,因為它比“F-bounded XXX”顯得更自然。

        6.它可能對文獻裡第一個例子實作編譯時冒泡排序沒有什麼用處。我對冒泡排序一直有相當病态的反感。不僅是因為這種排序算法幾乎從來就不适用于我的工作,而且也幾乎從來不值得在工作中考慮這種算法。哦,我離題了。

    7.初時,這點還不完全清楚。Sutter在《C++ Report》1997年9月刊上發表的文章裡并沒有将“basic guarantee”和“strong guarantee”歸功于Abrahams,但他提供并允許放在我的1999版《Effective C++》CD光牒的文章提到了Abrahams。我有十足把握公開說《C++ Report》發表的文章和Sutter提供給我的文章是不一樣的。

繼續閱讀