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

            chaosuper85

            C++博客 首頁 新隨筆 聯系 聚合 管理
              118 Posts :: 0 Stories :: 3 Comments :: 0 Trackbacks

            我們很難寫出所有可能被實例化的類型都合適的模板。某些情況下,

                通用模板定義對于某個類型可能是完全錯誤的,所以我們需要能夠實現處

                理某些特殊情況,特化的概念變是如此。compare函數和Queue類是這

                個問題的很好例子。因為與C風格字符串一起使用時,他們都不能正確工作

                template <typename T>
                int compare(const T &v1,const T &v2)
                {
                  if(v1 < v2) return -1;
                  if(v2 < v1) return 1;
                  return 0;
                }

                    如果用兩個const char* 實參調用這個模板定義,函數將比較指針的
                值。也就是比較兩個指針在內存中的相對位置,卻并沒有說明與指針所指
                數組的內容有關的任何事情。
                    為了能夠將compare函數用于字符串,必須提供一個知道怎樣比較C風
                格字符串的特殊定義。這些就被稱作是特化的,它對模板的用戶而言是透
                明的。


                1. 函數模板的特化
                特化形式:
                - 關鍵字template后面接一對空的尖括號<>;
                - 再接模板名和一對尖括號<>,尖括號中指定這個特化定義的模板參數:
                - 函數形參表
                - 函數體

                template<>
                int compare<const char*> (const char* const &v1,
                     const char* const &v2)
                {
                  return strcmp(v1,v2);
                }
                    特化的聲明必須與 對應的模板相匹配。類型形參固定為const char*。
                因此,函數形參是const char* 的const引用。當調用compare函數的時候,
                傳給它兩個字符指針,編譯器將調用特化版本。而不調用上面的泛型版本。
                  const  char *cp1 = "world", *cp2 = "hi";
                  int i1, i2;
                  compare(cp1, cp2); //調用特化函數模板
                  compare(i1, i2);   //調用泛型函數模板

                注意:
                * 函數模板特化時template<>不能省略,如果缺少結果是聲明該函數的重載


                * 必須包含函數形參列表。如果可以從形參列表推斷模板實參,則不必顯示

                   定模板實參。
                * 如果程序由多個文件構成,模板特化的聲明必須在使用該特化的每個文件
                   中出現。


                2.類模板的特化
                  當使用C風格字符串時,Queue類具有 compare函數相似的問題。問題就處
                在push函數中,該函數復制給定的值以創建Queue中的新元素。默認情況下


                復制C風格字符串只會復制指針,不會復制字符。而顯然復制指針將出現一


                列的嚴重問題。為了解決復制C風格字符串的問題,需要為const char*定義
                整個類的特化版本:
                  template<> class Queue<const char*>{
                  public:
                    void push(const char*);
                    void pop() {real_queue.pop();}
                    bool empty() const {return real_queue.front();}
                    //返回類型與模板參數類型不同
                    std::string front() {return real_queue.front();}
                    const std::string &front() const {return real_queue.front();

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

               3.特化成員而不特化類
                在上例的實現中,我們可以換一種方法,即不需要特化類,而只需要特化類
                的成員函數push、pop。

                根據函數模板特化的要求:
                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;   //隊列中沒有元素
                  eles{
                    tail->next = pt; //添加新元素到列尾
                    tail = pt;
                  }
                }

                template<>
                void Queue<const char*>::pop()
                {
                  QueueItem<const char*> *p = head;
                  delete head->item;  //刪除隊首元素
                  head = head->next;  //指向當前隊首元素
                  delete p;           //刪除零時指針
                }


                4.類模板的部分特化
                如果類模板有一個以上的模板形參,我們很有可能只要特化某些模板形參
                而不是全部形參。這時我們就需要使用類的部分特化。

                //定義模板類
                template <class T1, class T2>
                class some_template{
                  // ...
                };

                //定義模板類的部分特化:T2類型固定,部分特化T1類型
                template<class T1>
                class some_template<T1, int>{
                  // ...
                };

                //使用類模板的部分特化
                some_template<int, string> foo; //使用模板類
                some_template<string,int> bar;  //使用模板類的部分特化

                通過使用模板特化能解決一些在通常或者通用情況下無法解決的特殊問題。

                在掌握了基本的語法規范和實現方法后便可以加以應用。

             

            posted on 2009-08-11 18:58 chaosuper 閱讀(542) 評論(0)  編輯 收藏 引用
            波多野结衣中文字幕久久| 久久久久久久亚洲Av无码| 精品久久综合1区2区3区激情| 精品久久久久成人码免费动漫 | 狠狠色丁香婷婷久久综合| 色妞色综合久久夜夜| 欧洲精品久久久av无码电影| 2021少妇久久久久久久久久| 日本三级久久网| 久久AV高潮AV无码AV| 香蕉久久夜色精品国产小说| 亚洲精品国产第一综合99久久| 精品国产日韩久久亚洲| 国产精品免费看久久久香蕉 | AV无码久久久久不卡网站下载| 久久99精品久久久久久水蜜桃| 亚洲狠狠婷婷综合久久久久| 久久精品国产亚洲AV不卡| 精品久久人妻av中文字幕| 精品国产乱码久久久久软件 | 欧美日韩中文字幕久久久不卡| 麻豆久久久9性大片| 久久WWW免费人成—看片| 久久国产精品久久久| 久久精品毛片免费观看| 少妇人妻综合久久中文字幕| 久久精品国产国产精品四凭| 66精品综合久久久久久久| 久久精品人人做人人爽97| 久久午夜夜伦鲁鲁片免费无码影视| 久久国产午夜精品一区二区三区| 国产人久久人人人人爽| 久久超碰97人人做人人爱| 久久人人青草97香蕉| 欧美国产成人久久精品| 国产福利电影一区二区三区久久老子无码午夜伦不 | 久久久久亚洲精品天堂久久久久久| 国产精品对白刺激久久久| 老色鬼久久亚洲AV综合| 久久久久亚洲av无码专区导航| 无码人妻久久久一区二区三区|