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

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

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

1.模板特化

1.1概述

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

1.2函數(shù)模板特化

函數(shù)模板特化是在一個統(tǒng)一的函數(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)用實例: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;
}

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

i:10
p:very

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

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

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

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

1.3類模板特化

類模板特化類似于函數(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; //顯示模板實參的隱式實例化
a1.print();
A<char*> a2; //使用特化的類模板
A2.print();
}

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

A'num:6
A' special definition

2.模板偏特化

2.1概述

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

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

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

假如我們有一個compare函數(shù)模板,在比較數(shù)值類型時沒有問題,如果傳入的數(shù)值的地址,我們需要兩個數(shù)值的大寫,而非比較傳入的地址大小。此時我們需要對compare函數(shù)模板進行偏特化??疾烊缦麓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;
}

//對部分模板參數(shù)進行特化
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ù)特化為另一個模板類
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ù)模板的偏特化類似??疾烊缦麓a:

#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;
}
};

//對部分模板參數(shù)進行特化
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ù)特化為另一個模板類
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ù)特化為另一個模板類版本
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)先級

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

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

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

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

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

相關(guān)文章

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

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

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

    深入淺析C++的new和delete

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

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

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

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

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

    Swift編程中的泛型解析

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

    opencv實現(xiàn)顏色檢測

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

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

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

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

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

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

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

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

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

最新評論

曲阳县| 宣汉县| 蓝山县| 达拉特旗| 肥城市| 凤山县| 甘泉县| 施甸县| 华阴市| 玉龙| 芒康县| 锦屏县| 桂东县| 昌图县| 城步| 科尔| 渝北区| 广德县| 巩留县| 龙州县| 介休市| 延长县| 贵阳市| 双辽市| 海南省| 思茅市| 庆安县| 简阳市| 天气| 炎陵县| 兰州市| 祁阳县| 顺义区| 安义县| 永昌县| 尚义县| 莱州市| 平凉市| 九台市| 上饶市| 沅陵县|