亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

深入分析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)用,都會在目標(biāo)文件中生成該函數(shù)的二進制代碼。而如果使用模板的特化版本,除非發(fā)生函數(shù)調(diào)用,否則不會在目標(biāo)文件中包含特化模板函數(shù)的二進制代碼。這符合函數(shù)模板的“惰性實例化”準(zhǔn)則。
(2)如果使用普通重載函數(shù),那么在分離編譯模式下,應(yīng)該在各個源文件中包含重載函數(shù)的申明,否則在某些源文件中就會使用模板函數(shù),而不是重載函數(shù)。

1.3類模板特化

類模板特化類似于函數(shù)模板的特化,即類模板參數(shù)在某種特定類型下的具體實現(xiàn)。考察如下代碼。

#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++模板特化與偏特化的詳細(xì)內(nèi)容,更多關(guān)于C++模板特化與偏特化的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++實現(xiàn)關(guān)機功能詳細(xì)代碼

    C++實現(xiàn)關(guān)機功能詳細(xì)代碼

    大家好,本篇文章主要講的是C++實現(xiàn)關(guān)機功能詳細(xì)代碼,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • c++創(chuàng)建二維動態(tài)數(shù)組與內(nèi)存釋放問題

    c++創(chuàng)建二維動態(tài)數(shù)組與內(nèi)存釋放問題

    這篇文章主要介紹了c++創(chuàng)建二維動態(tài)數(shù)組與內(nèi)存釋放問題,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-06-06
  • C語言實現(xiàn)單詞小幫手

    C語言實現(xiàn)單詞小幫手

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)單詞小幫手,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • C++實現(xiàn)團購訂單管理系統(tǒng)

    C++實現(xiàn)團購訂單管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了如何利用C++實現(xiàn)團購訂單管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-12-12
  • c++禁止函數(shù)的傳值調(diào)用的方法

    c++禁止函數(shù)的傳值調(diào)用的方法

    這篇文章主要介紹了c++禁止函數(shù)的傳值調(diào)用的方法,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-08-08
  • C++運算符重載的詳細(xì)講解

    C++運算符重載的詳細(xì)講解

    這篇文章主要給大家介紹了關(guān)于C++運算符重載的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Visual Studio Code (vscode) 配置 C / C++ 環(huán)境的流程

    Visual Studio Code (vscode) 配置 C / C++ 環(huán)境的流程

    這篇文章主要介紹了Visual Studio Code (vscode) 配置 C / C++ 環(huán)境的流程,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-09-09
  • 記逆向小白的第一次vbsedit 9爆破及內(nèi)存補丁制作過程

    記逆向小白的第一次vbsedit 9爆破及內(nèi)存補丁制作過程

    這篇文章主要介紹了記逆向小白的第一次vbsedit 9爆破及內(nèi)存補丁制作過程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Qt利用QPainter實現(xiàn)基本繪圖的示例詳解

    Qt利用QPainter實現(xiàn)基本繪圖的示例詳解

    Qt?中提供了強大的?2D?繪圖系統(tǒng),可以使用相同的?API?在屏幕和繪圖設(shè)備上進行繪制,它主要基于QPainter、QPaintDevice?和?QPaintEngine?這三個類。本文主要和大家介紹一下QPainter實現(xiàn)的基本繪圖,感興趣的可以了解一下
    2022-12-12
  • c語言printf實現(xiàn)同一位置打印輸出的實例

    c語言printf實現(xiàn)同一位置打印輸出的實例

    下面小編就為大家?guī)硪黄猚語言printf實現(xiàn)同一位置打印輸出的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09

最新評論