• <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è)簡單的模版,現(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 語句來簡單的實(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è)簡潔的辦法。它可以根據(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)論排行榜

            2021国内久久精品| 久久久久亚洲AV成人网人人网站| 91亚洲国产成人久久精品| 性欧美丰满熟妇XXXX性久久久 | 夜夜亚洲天天久久| 久久人人爽人人爽人人AV| 99久久精品免费看国产一区二区三区| 久久亚洲精品无码播放| 无码任你躁久久久久久久| 欧美久久综合九色综合| 亚洲国产天堂久久综合| 久久乐国产综合亚洲精品| 一本色道久久88精品综合| 无码人妻久久一区二区三区免费丨| 亚洲精品无码久久一线| 无码伊人66久久大杳蕉网站谷歌 | 久久国产午夜精品一区二区三区| 久久精品无码av| 国产成年无码久久久免费| 久久精品国产久精国产思思| 国产69精品久久久久99尤物| 亚洲国产精品成人AV无码久久综合影院| 久久亚洲2019中文字幕| 国产精品伦理久久久久久| 一本一道久久a久久精品综合 | 99久久无码一区人妻a黑| 99久久精品九九亚洲精品| 久久免费视频1| 久久精品成人免费网站| 久久久久久久91精品免费观看| 久久久久亚洲AV无码网站| 久久亚洲中文字幕精品一区| 久久超碰97人人做人人爱| 精品久久人人爽天天玩人人妻| 中文精品久久久久人妻不卡| 国产福利电影一区二区三区久久老子无码午夜伦不| 久久久中文字幕日本| 亚洲av成人无码久久精品| 婷婷久久综合| 国内精品九九久久久精品| 伊人久久精品影院|