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

            天下

            記錄修行的印記

            C++ 高級主題之模板特化

            C++ 高級主題之模板特化
            我們很難寫出所有可能被實(shí)例化的類型都合適的模板。某些情況下,通用模板定義對于某個(gè)類型可能是完全錯(cuò)誤的,所以我們需要能夠?qū)崿F(xiàn)處理某些特殊情況,特化的概念變是如此。
            compare函數(shù)和Queue類是這個(gè)問題的很好例子。因?yàn)榕cC風(fēng)格字符串一起使用時(shí),他們都不能正確工作。
            template 
            <typename T>
            int compare(const T &v1,const T &v2)
            {
                
            if(v1 < v2) return -1;
                
            if(v2 < v1) return 1;
                
            return 0;
            }
            如果用兩個(gè)const 
            char* 實(shí)參調(diào)用這個(gè)模板定義,函數(shù)將比較指針的值。也就是比較兩個(gè)指針在內(nèi)存中的相對位置,卻并沒有說明與指針?biāo)笖?shù)組的內(nèi)容有關(guān)的任何事情。
            為了能夠?qū)ompare函數(shù)用于字符串,必須提供一個(gè)知道怎樣比較C風(fēng)格字符串的特殊定義。這些就被稱作是特化的,它對模板的用戶而言是透明的。

            1. 函數(shù)模板的特化
            特化形式:
            - 關(guān)鍵字template后面接一對空的尖括號<>;
            - 再接模板名和一對尖括號<>,尖括號中指定這個(gè)特化定義的模板參數(shù):
            - 函數(shù)形參表
            - 函數(shù)體
            template
            <>
            int compare<const char*> (const char* const &v1,const char* const &v2)
            {
                
            return strcmp(v1,v2);
            }
            特化的聲明必須與 對應(yīng)的模板相匹配。類型形參固定為const 
            char*
            因此,函數(shù)形參是const 
            char* 的const引用。當(dāng)調(diào)用compare函數(shù)的時(shí)候,
            傳給它兩個(gè)字符指針,編譯器將調(diào)用特化版本。而不調(diào)用上面的泛型版本。
            const  char *cp1 = "world"*cp2 = "hi";
            int i1, i2;
            compare(cp1, cp2); 
            //調(diào)用特化函數(shù)模板
            compare(i1, i2);  //調(diào)用泛型函數(shù)模板
            注意:
            * 函數(shù)模板特化時(shí)template<>不能省略,如果缺少結(jié)果是聲明該函數(shù)的重載。
            * 必須包含函數(shù)形參列表。如果可以從形參列表推斷模板實(shí)參,則不必顯示指定模板實(shí)參。
            * 如果程序由多個(gè)文件構(gòu)成,模板特化的聲明必須在使用該特化的每個(gè)文件中出現(xiàn)。

            2.類模板的特化
            當(dāng)使用C風(fēng)格字符串時(shí),Queue類具有 compare函數(shù)相似的問題。問題就處在push函數(shù)中,該函數(shù)復(fù)制給定的值以創(chuàng)建Queue中的新元素。默認(rèn)情況下,復(fù)制C風(fēng)格字符串只會復(fù)制指針,不會復(fù)制字符。而顯然復(fù)制指針將出現(xiàn)一系列的嚴(yán)重問題。為了解決復(fù)制C風(fēng)格字符串的問題,需要為const 
            char*定義整個(gè)類的特化版本:
            template
            <> 
            class Queue<const char*> 
            {
            public:
                
            void push(const char*);
                
            void pop() {real_queue.pop();}
                
            bool empty() const {return real_queue.front();}
                
            //返回類型與模板參數(shù)類型不同
                std::string front() {return real_queue.front();}
                
            const std::string &front() const {return real_queue.front();}
            private :
                Queue
            <std::string> real_queue;
            };

            給Queue一個(gè)新的數(shù)據(jù)元素,string對象的Queue。在類的外部定義一個(gè)成員:
            void Queue<const char*>::push (const char* val)
            {
                
            return real_queue.push(val);
            }
            這個(gè)函數(shù)通過調(diào)用read_queue的push函數(shù)把val指向的數(shù)組復(fù)制到未命名的string 對象中。當(dāng)需要出隊(duì)列的時(shí)候調(diào)用相應(yīng)real_queue.pop()函數(shù)即返回了這個(gè)string,從而解決了不用復(fù)制指針的問題。

            3.特化成員而不特化類在上例的實(shí)現(xiàn)中,我們可以換一種方法,即不需要特化類,而只需要特化類的成員函數(shù)push、pop。根據(jù)函數(shù)模板特化的要求:
            template 
            <>
            void Queue<const char*>::push(const char *const &val)
            {
                
            char * new_item = new char[strlen(val)+1];
                strncpy(new_item, val, strlen(val)
            +1);
                QueueItem
            <const char*> *pt = new QueueItem<const char*>(new_item);
                    
                
            if(empty())
                    head 
            = tail = pt;  //隊(duì)列中沒有元素
                eles{
                    tail
            ->next = pt; //添加新元素到列尾
                    tail = pt;
                }
            }
            template
            <>
            void Queue<const char*>::pop()
            {
                QueueItem
            <const char*> *= head;
                delete head
            ->item;  //刪除隊(duì)首元素
                head = head->next;  //指向當(dāng)前隊(duì)首元素
                delete p;            //刪除零時(shí)指針
            }

            4.類模板的部分特化
                如果類模板有一個(gè)以上的模板形參,我們很有可能只要特化某些模板形參
                而不是全部形參。這時(shí)我們就需要使用類的部分特化。
            //定義模板類
            template <class T1, class T2>
            class some_template{
                
            // 
            };

            //定義模板類的部分特化:T2類型固定,部分特化T1類型
            template<class T1>
            class some_template<T1, int>{
                
            // 
            };
            //使用類模板的部分特化
            some_template<intstring> foo; //使用模板類
            some_template<string,int> bar;  //使用模板類的部分特化
            通過使用模板特化能解決一些在通常或者通用情況下無法解決的特殊問題。在掌握了基本的語法規(guī)范和實(shí)現(xiàn)方法后便可以加以應(yīng)用。

            posted on 2013-06-26 11:36 天下 閱讀(1059) 評論(0)  編輯 收藏 引用 所屬分類: C/C++C++模板

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

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿(4)

            隨筆分類(378)

            隨筆檔案(329)

            鏈接

            最新隨筆

            搜索

            最新評論

            91精品观看91久久久久久| 激情五月综合综合久久69| 99久久免费国产特黄| 久久精品不卡| 国产色综合久久无码有码| 9999国产精品欧美久久久久久| 久久青青草原精品国产不卡| 精品少妇人妻av无码久久| 日韩电影久久久被窝网| 99国产欧美久久久精品蜜芽| 欧美日韩精品久久久久| 精品久久香蕉国产线看观看亚洲| 久久综合色之久久综合| 久久99热国产这有精品| 久久久久久国产a免费观看黄色大片| 国产精品久久网| 97久久婷婷五月综合色d啪蜜芽| 狠狠精品久久久无码中文字幕 | 久久99国产精品久久99| 91精品国产综合久久久久久| 日本久久久精品中文字幕| 久久精品国产精品亚洲精品 | 伊人久久大香线蕉综合Av| 91久久精品国产成人久久| 久久亚洲春色中文字幕久久久| 无码任你躁久久久久久| 国产精品成人99久久久久91gav | 午夜精品久久久久久| 国产免费久久久久久无码| 久久精品国产亚洲沈樵| 久久99国产综合精品| 久久久久高潮综合影院| 国产精品久久久久久久人人看| 久久精品?ⅴ无码中文字幕| 日本精品久久久久中文字幕| 国产精品久久国产精麻豆99网站| 亚洲国产欧洲综合997久久| 亚洲色大成网站WWW久久九九| 日本五月天婷久久网站| 久久无码国产专区精品| 成人综合久久精品色婷婷|