青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

大龍的博客

常用鏈接

統計

最新評論

被誤解的C++——模板和宏 (轉)

模板和宏
前些日子,論壇里大打口水仗的時候,有人提出這樣一個論斷:模板本質上是宏。于是,諸位高手為此好好辯論了一番。我原本也想加入論戰,但是覺得眾人的言論已經覆蓋了我的想法,所以也就作罷了。
盡管沒有參與討論,但“模板究竟和宏有什么關系”這個問題,始終在我的腦海中上下翻飛。每當我能夠放松下來的時候,這個問題便悄悄地浮現。(通常都是哄兒子睡下,然后舒舒服服地沖個熱水澡的時候:))。
我思索了半天,決定做些實際的代碼,以了解兩者的差異。現在,我把試驗的結果提交給大家,讓眾人來評判。
模板和宏是完全兩個東西,這一點毋庸置疑。模板的一些功能,宏沒有;宏的一些功能,模板沒有。不可能誰是誰的影子。我們這里主要想要弄清的是,模板的本質究竟是不是宏。
需要明確一下,所謂“本質”的含義。這里我假定:一樣東西是另一樣東西的“本質”,有么后者是前者的子集,要么后者是通過前者直接或間接地實現的,要么后者的基礎原理依賴于前者。如果哪位對此設定心存疑議,那么我們就得另行討論了。
首先,我編寫了一個模板,然后試圖編寫一個宏來實現這個模板的功能:
template<typename T>
class cls_tmpl
{
public:
string f1() {
strings=v.f()+”1000”;
return s;
}
void f2() {
v.g();
}
private:
Tv;
};
下面是宏的模擬:
#definecls_mcr(T) \
class \
{\
public:\
void f1() {\
v.f();\
}\
void f2() {\
v.g();\
}\
private:\
Tv;\
}
當我使用模板時,需要這么寫:
cls_tmpl<Tp1>ct;
使用宏的版本,這么寫:
cls_mcr(Tp1)cm;
兩者寫法一樣。但是下列代碼便出現問題:
cls_tmpl<Tp1>ct1;
cls_tmpl<Tp1>ct2;
ct1=ct2;//Ok,ct1和ct2是同樣的類型
cls_mcr(Tp1)cm1;
cls_mcr(Tp1)cm2;
cm1=cm2;//編譯錯誤,cm1和cm2的類型不同
由于cls_mcr(Tp1)兩次展開時,各自定義了一遍類,編譯器會認為他們是兩個不同的類型。但模板無論實例化多少次,只要類型實參相同,就是同一個類型。
這些便說明,模板和宏具備完全不同的語義,不可能用宏直接實現模板。如果要使宏避開這些問題,必須采用兩階段方式操作:
typedef cls_mcr(Tp1)cls_mcr_Tp1_;
cls_mcr_Tp1_cm1;
cls_mcr_Tp1_cm2;
cm1=cm2;//同一個類型,可以賦值
這反倒給了我們一個提示,或許編譯器可以在一個“草稿本”上把宏展開,然后通過用展開后的類名將所有用到的cls_mcr(…)替換掉。這樣便實現了模板。
但事情并沒有那么簡單。請考慮以下代碼:
class Tp1
{
public:
string f() {
return“X”;
}
};

cls_tmpl<Tp1>ct1;
ct1.f1();

cls_mcr(Tp1)cm1;//編譯錯誤:Tp1不包含成員函數g()
cm1.f1();
盡管模板和宏的代碼一樣,但是編譯器卻給出了不同的結果。回溯到cls_tmpl和cls_mcr的定義,兩者都有一個f2()成員函數訪問了Tp1的成員函數g()。但是,模板的代碼并沒有給出任何錯誤,而宏卻有編譯錯誤。要解釋清楚這個差異,先得了解一下C++模板的一個特殊的機制:模板中的代碼只有在用到時才會被實例化。也就是說,當遇到cls_tmpl<Tp1>時,編譯器并不會完全展開整個模板類。只有當訪問了模板上的某個成員函數時,才會將成員函數的代碼展開作語義檢查。所以,當我僅僅調用f1()時,不會引發編譯錯誤。只有在調用f2()時,才會有編譯錯:
ct1.f2();//編譯錯誤,Tp1不包含成員函數g()
這種機制的目的主要是為了減少編譯時間。但后來卻成為了泛型編程和模板元編程中非常重要的一個機制。(最早用于traits等方面,參見《C++ Template》一書。我在模擬屬性的嘗試中,也使用了這種機制,很好用。)
相反,宏是直接將所有的代碼同時展開,之后在編譯過程中執行全面的語言檢查,無論其成員函數使用與否。而模板一開始僅作語法檢查,只有使用到的代碼才做語義檢查和實際編譯。
從這一點看出,即使允許宏在“草稿本”中展開,它同模板在展開方式上也存在著巨大的差別。僅憑這一點,便可以否定“模板的本質是宏”這個論斷。但是,如果我們把眼光放寬一些,是否可以這么認為:盡管模板和宏采用了完全不同的展開方式,那么如果模板中的每個成員都看作獨立的宏,那么是否可以認為模板是通過一組宏,而不是一個宏,實現的呢?
讓我們來看模板cls_tmpl<>的成員函數f1():
string f1() {
strings=v.f()+”1000”;
return s;
}
如果我們把f1看作一個宏, f1在需要時以宏的方式展開,然后正式編譯。當然,我們首先必須將模板轉換成一組宏。如果哪個編譯器真是這樣做的,那么可以勉強地認為這個編譯器是通過宏實現模板的。(不過這種樣子的“宏”,還能算宏嗎?)
但是,當我們考慮另一個問題,事情就不再那么簡單了。請看以下代碼:
x=y;
a=b;
假設x、y、a、b都是int類型。這兩行代碼編譯后可能會變成如下等效的匯編代碼(實際上是機器碼):
mov eax, y
mov x, eax
mov eax, b
mov a, eax
我們可以看到,這兩行代碼分別轉化成兩條匯編指令,所不同的是參與的內存變量。可以認為編譯器把賦值的匯編碼(機器碼)做成一個“宏”:
#define assign(v1, v2) \
mov eax, v2\
mov v1, eax
在編譯時用內存變量(的地址)替換“宏”的參數。那么這種情況下,我們是否應該認為編譯器(或者說編譯)的本質是宏呢?
由于C++標準沒有規定用什么方式展開模板,而我們也很難知道各種編譯器是如何實現模板的,也就無從得知模板是否通過宏物理實現。但是,我個人的看法是,宏和模板都是語法層面的機制。如果一定要用宏這種語法層面的機制,來解釋模板的(物理)本質,那也太牽強附會了。
我覺得比較合理的解釋是:如果一定要把宏和模板扯上什么“親戚關系”,那么說宏是模板的遠方大表哥比較合理。兩者在技術上有一定的同源性。都是以標識符替換為基礎的。但是,其他在方面,我們很難說它們有多大的相似性或者關系。宏是語法層面的機制,而模板則深入到語義層面。無論是語法、語義,還是具體的實現,都沒有什么一樣的地方。
至于“模板的本質是宏”這種說法的始作俑者,可能是Stroupstrup本人。最初他提出模板(當時稱為類型參數)可以通過宏實現。但是不久以后,便發現他心目中的模板和宏有著天壤之別。于是,他和其他C++的創建者一起建立和發展了模板的各種機制。
故事本該就此結束,但是這個說法卻越傳越廣。我猜想原因有可能兩種。其一是為了使一些初學者理解模板的基本特征,用宏來近似地解釋以下模板,使人容易理解。我曾經對一些不開竅的同僚說:“如果你實在搞不清模板,可以把它理解成象宏那樣的東西。但是記住,它跟宏沒關系!”很多人話只聽半句。他們記住了前半句,扔掉了更重要的后半句。所以,我現在再也不說這樣的話了。
另一種原因可就險惡多了。一些試圖打壓C++的人總是不遺余力地貶損C++的各種特性,(C++的問題我們得承認,但是總得實事求是吧),特別是那些最強大的功能。而模板則是首當其沖的。如果把模板和宏,這種丑陋的、臭名昭著的“史前活化石”聯系在一起,對于打擊C++的名聲有莫大的幫助。(即便C++社群,也非常積極地排斥宏)。
實際上,模板的本質是不是宏,根本沒有什么實際意義。即便是這樣,也絲毫不會影響模板的價值。很多高級的編程機制都是建立在傳統的技術之上的,比如虛函數就是利用函數指針表和間接調用實現的。從沒有人拿這一點說事。
但是,很多人卻對模板大做文章,想借此說明模板在本質上是落后的東西。以此欺騙世人,特別是那些懵懂的初學者。我寫此文的目的,就是實在忍受不了這種指鹿為馬的言論,借此反擊一下。
另一方面,通過模板和宏的特性的比較,可以使我們更深入地了解和理解兩種機制的特性、能力和限制。溫故而知新,總會有新的收獲。

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/zdl1016/archive/2007/06/21/1660480.aspx

posted on 2010-03-31 10:05 大龍 閱讀(461) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲天堂av高清| 欧美日韩精品中文字幕| 亚洲欧洲一区二区三区久久| 久久精品国产亚洲一区二区| 香蕉乱码成人久久天堂爱免费| 中文国产成人精品| 中日韩美女免费视频网站在线观看| 亚洲性夜色噜噜噜7777| 性8sex亚洲区入口| 久久三级福利| 欧美国产欧美亚州国产日韩mv天天看完整| 欧美成人精精品一区二区频| 亚洲精品韩国| 亚洲欧美日韩国产一区| 久久久久久一区二区| 欧美黄色免费网站| 国产精品一区在线播放| 精品88久久久久88久久久| 亚洲美女视频在线观看| 亚洲永久在线观看| 麻豆国产精品777777在线 | 亚洲免费网址| 久久岛国电影| 日韩视频在线观看免费| 久久精品日产第一区二区三区 | 亚洲欧美日本国产有色| 麻豆av一区二区三区久久| 国产精品va在线播放我和闺蜜| 国产亚洲视频在线| 一区二区国产日产| 蘑菇福利视频一区播放| 午夜精品短视频| 欧美精品激情在线| 国产精品夜夜嗨| 99v久久综合狠狠综合久久| 久久免费午夜影院| 亚洲免费视频成人| 欧美美女bbbb| 亚洲精品乱码久久久久久蜜桃91| 久久久久国产精品人| 亚洲六月丁香色婷婷综合久久| 久久中文欧美| 亚洲二区视频在线| 久久另类ts人妖一区二区| avtt综合网| 欧美精品黄色| 亚洲九九精品| 亚洲国产天堂久久综合| 久久久久一区二区三区四区| 国产一区二区三区高清| 香蕉尹人综合在线观看| 亚洲图片激情小说| 国产精品久久久久av| 亚洲在线视频免费观看| 一区二区三区视频在线看| 欧美日韩国产综合新一区| 亚洲精品美女在线观看| 亚洲电影专区| 欧美黄色免费| 在线视频亚洲一区| 亚洲天堂激情| 国产精品视频你懂的| 欧美影院成年免费版| 亚洲欧美日韩中文在线制服| 国产精品久久久久久五月尺| 亚洲综合国产| 性色av一区二区三区在线观看| 国产日本欧美在线观看| 久久国产精品一区二区三区| 久久精品三级| 亚洲另类在线视频| 99国产精品国产精品毛片| 国产精品成人在线| 西西裸体人体做爰大胆久久久| 午夜伦欧美伦电影理论片| 国产综合色在线| 欧美黄色一级视频| 欧美午夜激情在线| 国产一区二区精品丝袜| 美女爽到呻吟久久久久| 久久夜色精品国产欧美乱| 在线观看视频一区二区| 亚洲第一视频网站| 欧美日韩一二三四五区| 欧美在线免费一级片| 久久久成人网| av成人天堂| 欧美一区二区三区久久精品| 亚洲第一精品夜夜躁人人爽| av成人老司机| 一区视频在线| 一区二区三区.www| 一区二区三区在线看| 日韩视频永久免费观看| 国产一区免费视频| 亚洲精品免费观看| 国语自产精品视频在线看| 亚洲乱码国产乱码精品精可以看| 国产一区二区三区高清在线观看| 亚洲精品1区| 国产欧美视频一区二区| 亚洲精选一区二区| 在线精品视频一区二区三四| 亚洲视频一区二区在线观看| 国产一区久久| 亚洲新中文字幕| 日韩午夜电影在线观看| 欧美自拍偷拍午夜视频| 亚洲视频自拍偷拍| 蜜臀av性久久久久蜜臀aⅴ四虎| 亚洲影视在线播放| 欧美成人精品在线观看| 久久久国产视频91| 国产精品网站一区| 99精品99| 日韩视频在线一区二区| 噜噜噜久久亚洲精品国产品小说| 欧美专区在线观看一区| 欧美日韩一区二区在线播放| 亚洲国产精品国自产拍av秋霞| 精品成人国产| 欧美专区在线| 久久久免费精品视频| 国产一区91| 午夜亚洲福利在线老司机| 午夜精彩视频在线观看不卡| 国产精品h在线观看| 99热这里只有成人精品国产| 亚洲精选一区二区| 欧美激情四色 | 亚洲小视频在线| 亚洲欧美制服中文字幕| 欧美视频福利| 99在线精品视频| 亚洲天堂网在线观看| 欧美精品在线一区二区| 亚洲激情亚洲| 亚洲神马久久| 国产精品一区一区三区| 欧美一区二区三区久久精品 | 一区二区三区视频免费在线观看| 欧美高清视频一区二区三区在线观看 | 欧美在线亚洲一区| 国产精品二区在线| 日韩亚洲欧美成人一区| 亚洲免费观看高清完整版在线观看熊| 欧美3dxxxxhd| 亚洲精品综合在线| 一本色道久久加勒比精品| 欧美日韩亚洲91| 一区二区三区高清视频在线观看| 亚洲欧美在线网| 黑人操亚洲美女惩罚| 欧美jizz19hd性欧美| 亚洲精品欧洲精品| 亚洲女同精品视频| 国产一二三精品| 欧美成人精品高清在线播放| 日韩午夜免费| 久久久精品tv| 99精品国产高清一区二区| 国产精品一国产精品k频道56| 亚洲欧美日韩精品久久久| 欧美成人久久| 亚洲午夜精品一区二区三区他趣| 国产伦一区二区三区色一情| 久久精品视频播放| 日韩亚洲欧美一区二区三区| 欧美影院成人| 日韩午夜三级在线| 国产日韩欧美另类| 免费观看成人鲁鲁鲁鲁鲁视频 | 欧美xxxx在线观看| 中文国产成人精品久久一| 欧美+亚洲+精品+三区| 亚洲一区二区三区乱码aⅴ| 伊人精品成人久久综合软件| 欧美色播在线播放| 蜜桃av一区| 香蕉久久久久久久av网站| 亚洲精品免费电影| 美女图片一区二区| 欧美与欧洲交xxxx免费观看| 亚洲免费黄色| 黄色日韩精品| 国产欧美日韩精品丝袜高跟鞋 | 一本色道久久| 在线观看欧美日韩| 国产精品自拍网站| 欧美日本一区二区三区| 久久精品亚洲乱码伦伦中文 | 欧美日韩在线不卡| 免费在线观看一区二区| 欧美一区二区视频在线观看2020| 99精品福利视频| 亚洲精品女人| 美日韩精品视频免费看| 欧美在线高清视频| 欧美一级精品大片| 午夜久久福利|