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

深入分析C++模板特化與偏特化

 更新時(shí)間:2020年08月25日 11:48:24   作者:Dabelv  
這篇文章主要介紹了C++模板特化與偏特化的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下

1.模板特化

1.1概述

模板特化(template specialization)不同于模板的實(shí)例化,模板參數(shù)在某種特定類型下的具體實(shí)現(xiàn)稱為模板的特化。模板特化有時(shí)也稱之為模板的具體化,分別有函數(shù)模板特化和類模板特化。

1.2函數(shù)模板特化

函數(shù)模板特化是在一個(gè)統(tǒng)一的函數(shù)模板不能在所有類型實(shí)例下正常工作時(shí),需要定義類型參數(shù)在實(shí)例化為特定類型時(shí)函數(shù)模板的特定實(shí)現(xiàn)版本。查看如下例子。

#include <iostream>
using namespace std;

template<typename T> T Max(T t1,T t2)
{
return (t1>t2)?t1:t2;
}

typedef const char* CCP;
template<> CCP Max<CCP>(CCP s1,CCP s2)
{
return (strcmp(s1,s2)>0)?s1:s2;
}

int main()
{
//調(diào)用實(shí)例:int Max<int>(int,int)
int i=Max(10,5);
//調(diào)用顯示特化:const char* Max<const char*>(const char*,const char*)
const char* p=Max<const char*>("very","good");
cout<<"i:"<<i<<endl;
cout<<"p:"<<p<<endl;
}

程序正常編譯運(yùn)行結(jié)果:

i:10
p:very

在函數(shù)模板顯示特化定義(Explicit Specialization Definition)中,顯示關(guān)鍵字template和一對(duì)尖括號(hào)<>,然后是函數(shù)模板特化的定義。該定義指出了模板名、被用來特化模板的模板實(shí)參,以及函數(shù)參數(shù)表和函數(shù)體。在上面的程序中,如果不給出函數(shù)模板Max< T>在T為const char*時(shí)的特化版本,那么在比較兩個(gè)字符串的大小時(shí),比較的是字符串的起始地址的大小,而不是字符串的內(nèi)容在字典序中先后次序。

除了定義函數(shù)模板特化版本外,還可以直接給出模板函數(shù)在特定類型下的重載形式(普通函數(shù))。使用函數(shù)重載可以實(shí)現(xiàn)函數(shù)模板特化的功能,也可以避免函數(shù)模板的特定實(shí)例的失效。例如,把上面的模板特化可以改成如下重載函數(shù)。

typedef const char* CCP;
CCP Max(CCP s1,CCP s2)
{
return (strcmp(s1,s2)>0)?s1:s2;
}

程序運(yùn)行結(jié)果和使用函數(shù)模板特化相同。但是,使用普通函數(shù)重載和使用模板特化還是有不同之處,主要表現(xiàn)在如下兩個(gè)方面:
(1)如果使用普通重載函數(shù),那么不管是否發(fā)生實(shí)際的函數(shù)調(diào)用,都會(huì)在目標(biāo)文件中生成該函數(shù)的二進(jìn)制代碼。而如果使用模板的特化版本,除非發(fā)生函數(shù)調(diào)用,否則不會(huì)在目標(biāo)文件中包含特化模板函數(shù)的二進(jìn)制代碼。這符合函數(shù)模板的“惰性實(shí)例化”準(zhǔn)則。
(2)如果使用普通重載函數(shù),那么在分離編譯模式下,應(yīng)該在各個(gè)源文件中包含重載函數(shù)的申明,否則在某些源文件中就會(huì)使用模板函數(shù),而不是重載函數(shù)。

1.3類模板特化

類模板特化類似于函數(shù)模板的特化,即類模板參數(shù)在某種特定類型下的具體實(shí)現(xiàn)??疾烊缦麓a。

#include <iostream>
using namespace std;

template<typename T>class A
{
T num;
public:
A()
{
num=T(6.6);
}
void print()
{
cout<<"A'num:"<<num<<endl;
}
};

template<> class A<char*>
{
char* str;
public:
A(){
str="A' special definition ";
}
void print(){
cout<<str<<endl;
}
};

int main()
{
A<int> a1; //顯示模板實(shí)參的隱式實(shí)例化
a1.print();
A<char*> a2; //使用特化的類模板
A2.print();
}

程序輸出結(jié)果如下:

A'num:6
A' special definition

2.模板偏特化

2.1概述

模板偏特化(template partitial specialization)是模板特化的一種特殊情況,指指定模板參數(shù)而非全部模板參數(shù),或者模板參數(shù)的一部分而非全部特性,也稱為模板部分特化。與模板偏特化相對(duì)的是模板全特化,指對(duì)所有的模板參數(shù)進(jìn)行特化。模板全特化與模板偏特化共同組成模板特化。

模板偏特化主要分為兩種,一種是指對(duì)部分模板參數(shù)進(jìn)行全特化,另一種是對(duì)模板參數(shù)特性進(jìn)行特化,包括將模板參數(shù)特化為指針、引用或是另外一個(gè)模板類。

2.2函數(shù)模板偏特化

假如我們有一個(gè)compare函數(shù)模板,在比較數(shù)值類型時(shí)沒有問題,如果傳入的數(shù)值的地址,我們需要兩個(gè)數(shù)值的大寫,而非比較傳入的地址大小。此時(shí)我們需要對(duì)compare函數(shù)模板進(jìn)行偏特化??疾烊缦麓a:

#include <vector>
#include <iostream> 
using namespace std;

//函數(shù)模板
template<typename T, class N> void compare(T num1, N num2)
{
cout << "standard function template" << endl;
if(num1>num2)
cout << "num1:" << num1 << " > num2:" << num2 <<endl;
else
cout << "num1:" << num1 << " <= num2:" << num2 << endl;
}

//對(duì)部分模板參數(shù)進(jìn)行特化
template<class N> void compare(int num1, N num2)
{
cout<< "partitial specialization" <<endl;
if (num1>num2)
cout << "num1:" << num1 << " > num2:" << num2 << endl;
else
cout << "num1:" << num1 << " <= num2:" << num2 << endl;
}

//將模板參數(shù)特化為指針
template<typename T, class N> void compare(T* num1, N* num2)
{
cout << "new partitial specialization" << endl;
if (*num1>*num2)
cout << "num1:" << *num1 << " > num2:" << *num2 << endl;
else
cout << "num1:" << *num1 << " <= num2:" << *num2 << endl;
}

//將模板參數(shù)特化為另一個(gè)模板類
template<typename T, class N> void compare(std::vector<T>& vecLeft, std::vector<T>& vecRight)
{
cout << "to vector partitial specialization" << endl;
if (vecLeft.size()>vecRight.size())
cout << "vecLeft.size()" << vecLeft.size() << " > vecRight.size():" << vecRight.size() << endl;
else
cout << "vecLeft.size()" << vecLeft.size() << " <= vecRight.size():" << vecRight.size() << endl;
}

int main()
{
compare<int,int>(30,31);//調(diào)用非特化版本compare<int,int>(int num1, int num2)

compare(30,'1'); //調(diào)用偏特化版本compare<char>(int num1, char num2)

int a = 30;
char c = '1';
compare(&a,&c); //調(diào)用偏特化版本compare<int,char>(int* num1, char* num2)

vector<int> vecLeft{0};
vector<int> vecRight{1,2,3};
compare<int,int>(vecLeft,vecRight); //調(diào)用偏特化版本compare<int,char>(int* num1, char* num2)
}

程序輸出結(jié)果如下:

standard function template
num1:30 <= num2:31
partitial specialization
num1:30 <= num2:1
new partitial specialization
num1:30 <= num2:1
to vector partitial specialization
vecLeft.size()1 <= vecRight.size():3

2.3類模板偏特化

類模板的偏特化與函數(shù)模板的偏特化類似。考察如下代碼:

#include <vector>
#include <iostream> 
using namespace std;

//類模板
template<typename T, class N> class TestClass
{
public:
static bool comp(T num1, N num2)
{
cout <<"standard class template"<< endl;
return (num1<num2) ? true : false;
}
};

//對(duì)部分模板參數(shù)進(jìn)行特化
template<class N> class TestClass<int, N>
{
public:
static bool comp(int num1, N num2)
{
cout << "partitial specialization" << endl;
return (num1<num2) ? true : false;
}
};

//將模板參數(shù)特化為指針
template<typename T, class N> class TestClass<T*, N*>
{
public:
static bool comp(T* num1, N* num2)
{
cout << "new partitial specialization" << endl;
return (*num1<*num2) ? true : false;
}
};

//將模板參數(shù)特化為另一個(gè)模板類
template<typename T, class N> class TestClass<vector<T>,vector<N>>
{
public:
static bool comp(const vector<T>& vecLeft, const vector<N>& vecRight)
{
cout << "to vector partitial specialization" << endl;
return (vecLeft.size()<vecRight.size()) ? true : false;
}
};

int main()
{
//調(diào)用非特化版本
cout << TestClass<char, char>::comp('0', '1') << endl; 

//調(diào)用部分模板參數(shù)特化版本
cout << TestClass<int,char>::comp(30, '1') << endl; 

//調(diào)用模板參數(shù)特化為指針版本
int a = 30;
char c = '1';
cout << TestClass<int*, char*>::comp(&a, &c) << endl; 

//調(diào)用模板參數(shù)特化為另一個(gè)模板類版本
vector<int> vecLeft{0};
vector<int> vecRight{1,2,3};
cout << TestClass<vector<int>, vector<int>>::comp(vecLeft,vecRight) << endl; 
}

程序輸出結(jié)果:

standard class template
1
partitial specialization
1
new partitial specialization
1
to vector partitial specialization
1

3.模板類調(diào)用優(yōu)先級(jí)

對(duì)主版本模板類、全特化類、偏特化類的調(diào)用優(yōu)先級(jí)從高到低進(jìn)行排序是:全特化類>偏特化類>主版本模板類。這樣的優(yōu)先級(jí)順序?qū)π阅芤彩亲詈玫摹?/p>

但是模板特化并不只是為了性能優(yōu)化,更多是為了讓模板函數(shù)能夠正常工作,最典型的例子就是STL中的iterator_traits。algorithm中大多數(shù)算法通過iterator對(duì)象來處理數(shù)據(jù),但是同時(shí)允許以指針代替iterator對(duì)象,這是為了支持C-Style Array。如果直接操作iterator,那么為了支持指針類型,每個(gè)算法函數(shù)都需要進(jìn)行重載,因?yàn)橹羔槢]有::value_type類型。為了解決這個(gè)問題,STL使用了iterator_traits對(duì)iterator特性進(jìn)行封裝,并為指針類型做了偏特化處理,算法通過它來操作iterator,不需要知道實(shí)際操作的是iterator對(duì)象還是指針。

template<typename IteratorClass> class iterator_traits
...
template<typename ValueType> class iterator_traits<ValueType*>
...
template<typename ValueType> class iterator_traits<ValueType const*>
...

后面兩是針對(duì)指針類型的偏特化,也是偏特化的一種常見形式。

以上就是深入分析C++模板特化與偏特化的詳細(xì)內(nèi)容,更多關(guān)于C++模板特化與偏特化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • visual?studio?2022一個(gè)不易發(fā)現(xiàn)的問題

    visual?studio?2022一個(gè)不易發(fā)現(xiàn)的問題

    本文主要介紹了visual?studio?2022一個(gè)不易發(fā)現(xiàn)的問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • 深入淺析C++的new和delete

    深入淺析C++的new和delete

    new和delete既是C++中的關(guān)鍵字也是一種特殊的運(yùn)算符。這篇文章主要介紹了C++的new和delete詳解,需要的朋友可以參考下
    2018-02-02
  • Qt基礎(chǔ)開發(fā)之Qt文件操作類QFile讀寫文件的詳細(xì)方法與實(shí)例及QDataStream的使用方法

    Qt基礎(chǔ)開發(fā)之Qt文件操作類QFile讀寫文件的詳細(xì)方法與實(shí)例及QDataStream的使用方法

    這篇文章主要介紹了Qt基礎(chǔ)開發(fā)之Qt文件操作類QFile讀寫文件的詳細(xì)方法與實(shí)例,需要的朋友可以參考下
    2020-03-03
  • Qt利用QChart實(shí)現(xiàn)實(shí)時(shí)波形圖的繪制

    Qt利用QChart實(shí)現(xiàn)實(shí)時(shí)波形圖的繪制

    這篇文章主要介紹了Qt如何利用QChart實(shí)現(xiàn)實(shí)時(shí)波形圖的繪制,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定是參考價(jià)值,需要的可以參考一下
    2022-06-06
  • Swift編程中的泛型解析

    Swift編程中的泛型解析

    這篇文章主要介紹了Swift編程中的泛型解析,是Swift入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-11-11
  • opencv實(shí)現(xiàn)顏色檢測(cè)

    opencv實(shí)現(xiàn)顏色檢測(cè)

    這篇文章主要為大家詳細(xì)介紹了opencv實(shí)現(xiàn)顏色檢測(cè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • OpenCV實(shí)現(xiàn)圖像腐蝕

    OpenCV實(shí)現(xiàn)圖像腐蝕

    這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)圖像腐蝕,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C語言如何寫類實(shí)現(xiàn)教程示例

    C語言如何寫類實(shí)現(xiàn)教程示例

    這篇文章主要為大家介紹了C語言如何寫類的實(shí)現(xiàn)教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • 淺談c++中的輸入輸出方法

    淺談c++中的輸入輸出方法

    下面小編就為大家?guī)硪黄獪\談c++中的輸入輸出方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-06-06
  • C語言實(shí)現(xiàn)一個(gè)多線程委托模型的示例詳解

    C語言實(shí)現(xiàn)一個(gè)多線程委托模型的示例詳解

    這篇文章主要介紹了C語言實(shí)現(xiàn)一個(gè)多線程委托模型,這就是一個(gè)使用C語言實(shí)現(xiàn)多線程委托模型的例子,其中包含boss線程和worker線程,可以處理工作線程的異常情況,需要的朋友可以參考下
    2023-06-06

最新評(píng)論

武威市| 鹤岗市| 长泰县| 宁化县| 绥芬河市| 吉木萨尔县| 息烽县| 农安县| 宜州市| 承德市| 长丰县| 茌平县| 布尔津县| 泸溪县| 汉源县| 贡山| 泗水县| 始兴县| 石台县| 英德市| 镇原县| 门头沟区| 专栏| 临西县| 日喀则市| 洞头县| 观塘区| 黎平县| 曲水县| 三原县| 锦屏县| 潢川县| 原阳县| 罗源县| 丹巴县| 溧水县| 湘乡市| 灌云县| 大邑县| 偃师市| 五指山市|