• <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)論排行榜

            激情五月综合综合久久69| 77777亚洲午夜久久多喷| 久久伊人中文无码| 久久人人爽爽爽人久久久| 久久精品国产99国产电影网| 欧美久久综合九色综合| 久久久久亚洲AV无码网站| 久久午夜福利电影| 久久99精品久久久久久hb无码| 久久精品无码一区二区日韩AV | 欧美日韩中文字幕久久伊人| 久久亚洲高清综合| 国产精品久久久久久| 亚洲精品白浆高清久久久久久 | 久久99精品久久久久久动态图| 狠狠久久综合伊人不卡| 久久久久AV综合网成人| 久久综合偷偷噜噜噜色| 91精品婷婷国产综合久久 | 麻豆国内精品久久久久久| 国产精品久久久久…| 久久ww精品w免费人成| 老男人久久青草av高清| 亚洲国产香蕉人人爽成AV片久久| 香港aa三级久久三级| 精品久久久久久成人AV| 亚洲综合精品香蕉久久网| 伊人久久大香线蕉AV一区二区| 国产精品九九久久精品女同亚洲欧美日韩综合区 | 久久久久久久波多野结衣高潮 | 久久99精品久久久久久秒播 | 中文字幕久久久久人妻| 亚州日韩精品专区久久久| 国产免费久久精品99久久| 久久九九全国免费| 久久免费国产精品一区二区| 97久久超碰成人精品网站| 99精品久久精品| 久久国产精品成人免费| 99久久国产亚洲高清观看2024| 久久国产免费观看精品|