最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解讀C++編程中類模板的三種特化

 更新時(shí)間:2016年01月08日 17:08:19   作者:MasterFT  
這篇文章主要介紹了C++編程中類模板的三種特化,需要的朋友可以參考下

1.類模板顯式特化
為了進(jìn)行特化,首先需要一個(gè)通用的版本,稱主模板.主模板使用了標(biāo)準(zhǔn)庫堆算法.  堆 是一種線性化的樹形結(jié)構(gòu),將一個(gè)值壓入一個(gè)堆中, 實(shí)際上等于將該值插入到一個(gè)樹形結(jié)構(gòu)中;將一個(gè)值從堆中取出就等于移除并返回堆中最大值.但在處理字符的指針時(shí)會碰釘子.堆將按照指針的值進(jìn)行組織. 我們可以提供一個(gè)顯式特化版本解決此問題(例1)如果希望除了一個(gè)針對const char*的Heap外,還希望提供一個(gè)針對char *的Heap;(例2)

//主模板
template <typename T>
class Heap
{
private:
  std::vector<T> h_;
public:
  void push(const T& val);
  T pop();
  bool empty() const //const聲明在末尾表示該函數(shù)不能修改類變量
  {
    return h_.empty();
  }
}

template <typename T>
void Heap<T>::push(const T& val)
{
  h_.push_back(val);
  std::push_heap(h_.begin(),h_.end());
}

template <typename T>
T Head<T>::pop()
{
  std::pop_head(h_.begin(),h_.end());
  T tmp(h_.back());
  h_.pop_back();
  return tmp;
}

例1

//顯示特化版本
/***********************************************
 *     可以看到模板參數(shù)列表是空的,其實(shí)這根本不是一個(gè)模
 *  板. 因?yàn)闆]有指定任何模板參數(shù).所以模板的顯式特化又被
 *  稱作"完全特化".
 *     Heap<const char*> 完全特化,不會導(dǎo)致模板的實(shí)例化;
 *     Heap<int> 特化,會導(dǎo)致模板的實(shí)例化;
 *     編譯器根據(jù)主模板的聲明來檢查類模板特化.
***********************************************/
template<>//注意,無任何參數(shù),當(dāng)然,它本來就不是一個(gè)模板
class Head<const char *>
{
private:
  std::vector<const char *> h_;
public:
  void push(const char *pval);
  const char * pop();
  bool empty() const //const聲明在末尾表示該函數(shù)不能修改類變量
  {
    return h_.empty();
  }
};
//再次提醒, Head<const char *>不是一個(gè)模板
void Heap<const char*>::push(const char *pval)
{
  h_.push_back(pval);
  std::push_heap(h_.begin(),h_.end());
}

例2

/***********************************************
 *     C++沒有要求顯式特化的接口必須和主模板的接口完全
 *  匹配.如該例中,沒有定義主模板的empty函數(shù),并且自行增加
 *  了size和capitalize兩個(gè)函數(shù).
 *     提醒:此例中不定義empty函數(shù)是不可取的,定義模板的
 *  顯式特化和類的派生之間雖然不存在任何技術(shù)上的聯(lián)系,但
 *  是用戶依然可以參考類的派生的優(yōu)點(diǎn),讓特化版本至少具有
 *  主模板的基本能力.
***********************************************/
template<>//注意,無任何參數(shù),當(dāng)然,它本來就不是一個(gè)模板
class Head<char *>
{
private:
  std::vector<char *> h_;
public:
  void push(char *pval);
  char * pop();
  //注意,此處沒有提供empty函數(shù)喲!!!
  size_t size() const;
  void capitalize();
};

2.模板局部特化
模板局部特化首先要聲明的是,C++還不支持對函數(shù)模板的局部特化,所以此處我們只討論類模板的局部特化.我們依然首先需要一個(gè)主模板.(參考類模板顯式特化) 自我理解:如果針對不能的指針定義不同的完全特化,豈不是太麻煩了,有沒有更好的辦法呢?那就是局部特化了.(例1)提示: 局部特化它是一個(gè)模板.完全特化不是一樣模板.

例1

/***********************************************
 *  局部特化 
 *     和完全特化不同,這里的Heap參數(shù)類型只是被部分的確
 *  定為T*,而T是一個(gè)未指定的類型,這就是為什么說它是局部
 *  特化的原因;
 *     當(dāng)使用一個(gè)未經(jīng)任何修飾的指針類型來實(shí)例化Heap時(shí),
 *  局部特化將優(yōu)先于主模板;
 *     當(dāng)使用const char * 或 char *(參考類模板顯式特化)來
 *  實(shí)例化Heap時(shí),此時(shí)完全特化又會優(yōu)先于局部特化.
 *  Heap<std::string> h1;  主模板  T是std::string
 *  Heap<std::string *> h2;  局部特化  T是std:string
 *  Heap<int **> h3;    局部特化 T是int *
 *  Heap<char *> h4;  完全特化 T是char *
 *  Heap<const int *> h5;  局部特化 T是const int
 *  Heap<int (*)()> h6;  局部特化 T是int()
***********************************************/
template <typename T>
class Heap<T *> //注意這里
{
private:
  std::vector<T *>h_;
public:
  void push(const T *val);
  T *pop();
  bool empty()
  {
    return h_.empty();
  }
};

template <typename T>
void Heap<T *>::push(const T *val)
{
  //......
}

例2

/***********************************************
 *     有一點(diǎn)很微妙但很有用:主模板的完全特化或局部特化
 *  必須采用與主模板相同數(shù)量和類型的實(shí)參進(jìn)行實(shí)例化,但它
 *  的模板的參數(shù)并不需要具有和主模板相同的形式.
***********************************************/
//定義一個(gè)模板,有三個(gè)模板參數(shù),書寫形式如下
template <typename R,typename A1,typename A2> 
//注意,局部特化中,模板參數(shù)也是三個(gè),但書寫形式可不一樣嘍
class Heap<R (*) (A1,A2)>
{
  //......
};

Heap<char *(*) (int,int)> h7; //R是char *,A1和A2是int
//把 char *(*) (int,int) 想象成一個(gè)"指向有兩個(gè)參數(shù)的非成員函數(shù)的指針"

template <class C,typename T>
class Heap<T C::*>
{
  //......
};
Heap<std::string Name::*> h8;//T是string,C是Name

盡管為何需要對這些東西使用Heap只是一個(gè)猜測,先知道有這么一用法吧!

3.類模板成員特化

雖然模板的特化和類的派生之間沒有任何關(guān)系, 但在特化模板的時(shí)候,不妨借鑒一下派生的精神.也就意味著一個(gè)完全特化或局部特化通常必須重新實(shí)現(xiàn) 主模板具備的所有能力.
例:

//主模板
template <typename T>
class Heap
{
private:
  std::vector<T> h_;
public:
  void push(const T& val);
  T pop();
  bool empty() const //const聲明在末尾表示該函數(shù)不能修改類變量
  {
    return h_.empty();
  }
}
//其實(shí)我們真正需要特化的是 push 和 pop兩個(gè)函數(shù).
//對比顯式特化,它是通過主模板,再寫一個(gè)模板顯式特化版本類;
//而這里只是對類模板成員進(jìn)行了單獨(dú)特化.
template<>
void Heap<const char*>::push(const char *const &pval)
{
  h_.push_back(pval);
  std::push_heap(h_.begin(),h_.end(),strLess);
}

template<>
const char* Heap<const char*>::pop()
{
  std:pop_heap(h_.begin(),h_end(),strLess);
  const char* tmp = h_.back();
  h_.pop_back();
  return tmp;
}


注意,這些函數(shù)的接口必須和 "它們正在特化其成員" 的模板的相應(yīng)接口相匹配.如例1, 就得和主模板的接口相匹配.而如果你是自己再定義的一個(gè)顯式/局部特化版本類,就不需要匹配 一致.(見顯式特化和局部特化),最后指出兩點(diǎn): 首先,除了成員函數(shù)外,其實(shí)成員也可以被顯式特化,如靜態(tài)成員和成員模板.其次,顯式特化是為模板或模板成員提供定制版本的一種手段;而顯式實(shí)例化僅僅是明確地告訴編譯器去實(shí)例化一個(gè)成員.       

相關(guān)文章

  • C語言的運(yùn)算符你了解嗎

    C語言的運(yùn)算符你了解嗎

    這篇文章主要介紹了C語言中的運(yùn)算符,本文給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下,希望能給你帶來幫助
    2021-08-08
  • C++ vector操作實(shí)現(xiàn)

    C++ vector操作實(shí)現(xiàn)

    這篇文章主要介紹了C++ vector操作實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • C++中的throw關(guān)鍵字詳解

    C++中的throw關(guān)鍵字詳解

    throw關(guān)鍵字是在C語言中用來拋出異常的關(guān)鍵字,它通常與try和catch一起使用,用于在程序中發(fā)生錯(cuò)誤時(shí)進(jìn)行異常處理,當(dāng)遇到無法處理的錯(cuò)誤情況時(shí),我們可以使用throw關(guān)鍵字主動(dòng)拋出異常,所以本文給大家詳細(xì)的介紹一下C++中的throw關(guān)鍵字,需要的朋友可以參考下
    2023-09-09
  • C語言實(shí)現(xiàn)父進(jìn)程主動(dòng)終止子進(jìn)程的方法總結(jié)

    C語言實(shí)現(xiàn)父進(jìn)程主動(dòng)終止子進(jìn)程的方法總結(jié)

    一般的情況,子進(jìn)程自己運(yùn)行完后,執(zhí)行exit 或者return 后,父進(jìn)程wait.  waitpid收回子進(jìn)程,但子進(jìn)程是一個(gè)循環(huán)等待狀態(tài)不主動(dòng)退出,父進(jìn)程可以采用文中介紹的幾種方法,需要的朋友可以參考下
    2023-10-10
  • C++ 智能指針的模擬實(shí)現(xiàn)實(shí)例

    C++ 智能指針的模擬實(shí)現(xiàn)實(shí)例

    這篇文章主要介紹了C++ 智能指針的模擬實(shí)現(xiàn)實(shí)例的相關(guān)資料,智能指針是一個(gè)類,它把普通指針封裝起來,能實(shí)現(xiàn)和普通指針同樣的功能。,需要的朋友可以參考下
    2017-07-07
  • C語言實(shí)現(xiàn)繪制繞線畫的示例代碼

    C語言實(shí)現(xiàn)繪制繞線畫的示例代碼

    繞線畫簡單點(diǎn)來說,就是在木板上釘一圈釘子,通過繞線進(jìn)行構(gòu)圖,最終呈現(xiàn)出一幅圖像。本文將用C語言實(shí)現(xiàn)這一效果,感興趣的小伙伴可以嘗試一下
    2022-11-11
  • C++ Sort函數(shù)使用場景分析

    C++ Sort函數(shù)使用場景分析

    sort函數(shù)是algorithm庫下的一個(gè)函數(shù),sort函數(shù)是不穩(wěn)定的,即大小相同的元素在排序后相對順序可能發(fā)生改變,如果某些場景需要保持相同元素間的相對順序,可使用stable_sort函數(shù),接下來通過本文給大家介紹C++ Sort函數(shù)詳解,感興趣的朋友一起看看吧
    2025-04-04
  • C++實(shí)現(xiàn)學(xué)生選課系統(tǒng)

    C++實(shí)現(xiàn)學(xué)生選課系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)學(xué)生選課系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • 詳解C++中的vector容器及用迭代器訪問vector的方法

    詳解C++中的vector容器及用迭代器訪問vector的方法

    使用迭代器iterator可以更方便地解引用和訪問成員,當(dāng)然也包括vector中的元素,本文就來詳解C++中的vector容器及用迭代器訪問vector的方法,需要的朋友可以參考下
    2016-05-05
  • Opencv實(shí)現(xiàn)綠幕視頻背景替換功能

    Opencv實(shí)現(xiàn)綠幕視頻背景替換功能

    這篇文章主要為大家詳細(xì)介紹了Opencv實(shí)現(xiàn)綠幕視頻背景替換功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-05-05

最新評論

稷山县| 库尔勒市| 玛纳斯县| 新津县| 文化| 凤翔县| 德庆县| 宜章县| 讷河市| 米脂县| 县级市| 晋宁县| 合阳县| 松江区| 福泉市| 翁牛特旗| 法库县| 略阳县| 依安县| 黄龙县| 扶余县| 高清| 思南县| 福建省| 吉隆县| 信阳市| 都匀市| 玛沁县| 呼和浩特市| 安新县| 抚远县| 榕江县| 万源市| 东兰县| 循化| 通辽市| 团风县| 夏邑县| 鹤峰县| 胶南市| 贵阳市|