• <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>

            牧光小院

            被約束的日日夜夜,停不下來的時(shí)間。

            C++的靜態(tài)分派技術(shù)

            我們可以用不同的整數(shù)來實(shí)例化同一個(gè)模板,從而構(gòu)造不同的類型,進(jìn)而在編譯期執(zhí)行某些抉擇。


            Alexandrescu 最初設(shè)計(jì)的一個(gè)簡(jiǎn)單的模版,現(xiàn)在成了泛型設(shè)計(jì)的常用手法:

            template <int v>

            struct Int2Type {

            ??? enum { value? = v };

            };

            對(duì)于每一個(gè)不同的常整數(shù), Int2Type 都代表不同的類型。這是因?yàn)椴煌哪0鎸?shí)例化都代表不同的類型,也就是說 Int2Type<0> Int2Type<1> 是完全不同的。

            當(dāng)你想根據(jù)編譯時(shí)結(jié)果來進(jìn)行某些抉擇——例如選擇不同的函數(shù)——時(shí),你可以依賴一個(gè)常整數(shù)來幫你完成分派工作,這時(shí) Int2Type 便可以幫你是實(shí)現(xiàn)這個(gè)方法。

            一般來說,你在下面兩個(gè)情況中需要使用 Int2Type

            l ???????? 你需要根據(jù)編譯時(shí)常量來調(diào)用不同的函數(shù)

            l ???????? 你需要在編譯時(shí)執(zhí)行分派工作

            如果是在運(yùn)行時(shí)執(zhí)行分派工作,你可以用 if-else switch 語(yǔ)句來簡(jiǎn)單的實(shí)現(xiàn)。在大部分的時(shí)候,這種運(yùn)行時(shí)成本都是微不足道的。但是,有時(shí)它們卻不能滿足你的要求。既是是在編譯期可以決定其分支,編譯器還是會(huì)勤勞的為你編譯其所有的分支,這也就意味著 if-else 的所有分支必須被成功編譯。有些困惑?繼續(xù)看下去:

            考慮下面的情形:你設(shè)計(jì)了一個(gè)泛型容器 NiftyContainer

            template <class T> class NiftyContainer {

            ??? ...

            };

            NiftyContainer 容器包含指向 T 對(duì)象的指針。為了復(fù)制 NiftyContainer 中的一個(gè)對(duì)象,你可能需要調(diào)用 T 的拷貝構(gòu)造函數(shù)(對(duì)于非多態(tài)類型)或者一個(gè)名為 Clone() 的虛函數(shù)(對(duì)于多態(tài)類型)。你可以通過設(shè)置一個(gè) bool 類型的模版參數(shù)來從類的客戶手里獲得關(guān)于多態(tài)的信息。

            template <class T, bool isPolymorphic> class NiftyContainer {

            ??? // Other actions

            ??? void DoSomething() {

            ?????? T* pSomeObj = ...;

            ?????? if(isPolymorphic) {

            ?????????? T* pNewObj = pSomeObj->Clone();

            ?????????? // Some polymorphic algorithm

            ?????? }

            ?????? else {

            ?????????? T* pNewObj = new T(*pSomeObj);

            ?????????? // Some non-polymorphic algorithm

            ?????? }

            ??? }

            };

            問題在于編譯器不會(huì)讓你僥幸編譯上面的代碼。例如,如果一個(gè)多態(tài)類型沒有定義 Clone() ,那么 NiftyContainer::DoSomething 絕對(duì)不會(huì)通過編譯。盡管在編譯時(shí)我們肯定可以對(duì)于分支進(jìn)行判斷,但這畢竟不是編譯器的工作,他只會(huì)勤勞的為你編譯出所有的代碼。于是當(dāng)你試圖調(diào)用 NiftyContainer<int, false>::DoSomething 的時(shí)候,編譯器還是會(huì)停在 pObj->Clone() 上,并且抱怨說:“你在做什么?”

            對(duì)于非多態(tài)類型分支,也有可能發(fā)生編譯錯(cuò)誤。如果 T 是一個(gè)多態(tài)類型,并且把它的拷貝構(gòu)造函數(shù)設(shè)定為 private 的時(shí)候(這時(shí)一個(gè)多態(tài)類的良好行為),非多態(tài)分支的 new T(*pObj) 就會(huì)發(fā)生錯(cuò)誤。

            你可能會(huì)想,如果編譯器可以不去理會(huì)那些不必要的分支就好了,但是看來不太可能。那么,如何是好呢?

            其實(shí),方法有很多, Int2Type 提供了一個(gè)簡(jiǎn)潔的辦法。它可以根據(jù) true false 來生成兩個(gè)不同的類型,而后根據(jù) Int2Type<isPolymorphic> 評(píng)估正確的調(diào)用。

            template <class T, bool isPolymorphic> class NiftyContainer {

            private :

            ??? // Other actions

            ??? void DoSomething(T* pObj, Int2Type<true>) {

            ?????? T* pNewObj = pSomeObj->Clone();

            ?????? // Some polymorphic algorithm

            ??? }

            ??? void DoSomething(T* pObj, Int2Type<false>) {

            ?????? T* pNewObj = new T(*pSomeObj);

            ?????? // Some non-polymorphic algorithm

            ??? }

            public :

            ??? void DoSomething(T* pObj) {

            ?????? DoSomething(pObj, Int2Type<isPolymorphic>());

            ??? }

            };

            當(dāng)你想把常整數(shù)用作一個(gè)類型的時(shí)候, Int2Type 是非常方便的。你可以傳遞一個(gè)臨時(shí)的變量來重載函數(shù)。而之所以我們可以這樣做,是因?yàn)榫幾g器不會(huì)去編譯沒有用到的模板函數(shù)。

            posted on 2005-11-11 11:42 nacci 閱讀(2378) 評(píng)論(2)  編輯 收藏 引用 所屬分類: C++漫談

            評(píng)論

            # re: C++的靜態(tài)分派技術(shù) 2005-11-15 16:36 christanxw

            這在STL中有著廣泛的應(yīng)用  回復(fù)  更多評(píng)論   

            # re: C++的靜態(tài)分派技術(shù) 2008-07-25 09:58 tomlau

            真好,學(xué)習(xí)了  回復(fù)  更多評(píng)論   

            <2006年5月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿(2)

            隨筆分類

            收藏夾

            大家的聲音

            積分與排名

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久天天躁狠狠躁夜夜avapp| 久久人人爽人人爽人人片AV东京热| 国产精品99久久久久久宅男| 国产精品视频久久久| 91精品国产高清久久久久久国产嫩草| 成人精品一区二区久久久| 久久人人爽人人澡人人高潮AV| 欧洲性大片xxxxx久久久| 亚洲AV无码久久精品蜜桃| 亚洲国产精品婷婷久久| 久久毛片一区二区| 国产精品久久久福利| 欧美日韩精品久久免费| 99久久国产免费福利| 色偷偷久久一区二区三区| 久久久久亚洲AV成人网人人软件| 精品国产青草久久久久福利| 久久人人爽人人澡人人高潮AV | 国产成人精品久久| 久久综合中文字幕| 蜜臀av性久久久久蜜臀aⅴ| 国产精品免费看久久久香蕉| 久久香蕉超碰97国产精品| 久久精品亚洲欧美日韩久久| 91精品国产高清91久久久久久| 久久九九久精品国产免费直播| 久久精品国产国产精品四凭| 91精品国产高清久久久久久91 | 精品久久久久久综合日本| 一本久久a久久精品亚洲| 亚洲第一永久AV网站久久精品男人的天堂AV | 亚洲国产成人久久精品影视| 无码超乳爆乳中文字幕久久| 久久精品中文字幕大胸| 久久久久亚洲精品中文字幕| 99久久国产综合精品成人影院| 欧美噜噜久久久XXX| 人妻无码久久一区二区三区免费| 久久SE精品一区二区| 少妇久久久久久久久久| 久久久久成人精品无码中文字幕|