目錄
1.類模闆特化
1.1類模闆全特化
1.1.1正常全特化
1.1.2類模闆偏特化(局部特化)
2.函數模闆特化
2.1 函數模闆全特化
2.2 函數模闆不能偏特化
3.模闆特化版本放置位置建議
1.類模闆特化
特化:相反的是 泛化:模闆,可以随便指定類型
特化:對特殊的類型(類型模闆參數)進行特殊的對待。
1.1類模闆全特化
1.1.1正常全特化
必須先有泛化版本才能存在特化版本。隻要設計特化,就一定存在泛化
特化版本代碼編譯器會優先選擇
#include <iostream>
#include <string>
using namespace std;
template <typename T,typename U>
struct TC // 泛化的TC類模闆
{
TC()
{
cout << "泛化版本構造函數" << endl;
}
void functest()
{
cout << "泛化版本" << endl;
}
};
// 當T與U這兩個類型模闆參數都為int類型時,我們希望做一個特化版本
// 全特化就是所有類型模闆參數,都需要用具體的類型代表
// 全特化表示所有類型模闆參數都用具體類型代表,
// 是以這裡template後面的<>裡為空
template <>
struct TC<int,int> // 上面的T綁定到第一個int,上面的U綁定到第二個int
{
TC()
{
cout << "特化版本構造函數" << endl;
}
// 對特化版本進行單獨處理
void functest()
{
cout << "int,int的特化版本" << endl;
}
};
// 當T與U這兩個類型模闆參數都為int類型時,我們希望做一個特化版本
// 全特化就是所有類型模闆參數,都需要用具體的類型代表
// 全特化表示所有類型模闆參數都用具體類型代表,
// 是以這裡template後面的<>裡為空
template <>
// 上面的T綁定到第一個double,上面的U綁定到第二個int
struct TC<double, int>
{
void functest()
{
cout << "double,int的特化版本" << endl;
}
};
int main()
{
// 調用int,int特化版本
TC<int, int> dc;
dc.functest();
// 調用泛化版本
TC<char, int> tchar;
tchar.functest();
system("pause");
return 0;
}
4-6類和函數的模闆全特化、偏特化(局部特化)1.類模闆特化2.函數模闆特化3.模闆特化版本放置位置建議

特化成員函數而不是模闆
#include <iostream>
#include <vector>
#include <string>
#include <map>
using namespace std;
template <typename T , typename U>
struct TC //泛化的TC版本
{
TC()
{
cout <<"泛化版本的構造函數" << endl;
}
void function()
{
cout << "泛化版本" << endl;
}
};
template <>
void TC<int ,int>:: function ()
{
cout << "int int的function()特化版本" << endl;
}
int main()
{
TC<int,int> tech; //調用泛化版本的構造函數
tech.function(); //因為我們特化了int ,int類型的
}
1.1.2類模闆偏特化(局部特化)
偏特化從兩個方面說起:一個是從 模闆數量,一個是從模闆參數範圍上。
#include <iostream>
#include <vector>
#include <string>
#include <map>
using namespace std;
template <typename T , typename U ,typename W>
struct TC
{
void functest()
{
cout << "泛化版本" <<endl;
}
};
//從參數數量上進行偏特化,我們現在綁定2個類型模闆參數
template <typename U>
struct TC<int,U,double> //這裡可以跳轉
{
void functest()
{
cout <<"偏特化版本" <<endl;
}
};
int main()
{
//數量上
TC<double,int,double> tech;
tech.functest();
TC<int ,int ,double> tech1;
tech1.functest();
}
#include <iostream>
#include <string>
using namespace std;
template <typename T>
struct TC // 泛化的TC類模闆
{
TC()
{
cout << "泛化版本構造函數" << endl;
}
void functest()
{
cout << "泛化版本" << endl;
}
};
// 模闆參數範圍上的特化版本
template <typename T>
struct TC<const T>
{
TC()
{
cout << "const類型特化版本構造函數" << endl;
}
void functest()
{
cout << "const類型特化版本" << endl;
}
};
// 模闆參數範圍上的特化版本
template <typename T>
struct TC<T*>
{
TC()
{
cout << "指針類型偏特化版本構造函數" << endl;
}
void functest()
{
cout << "指針類型特化偏版本" << endl;
}
};
int main()
{
// 模闆參數範圍上的特化版本
TC<const int> dc;
dc.functest();
// 模闆參數範圍上的特化版本
TC<int *> dx;
dx.functest();
system("pause");
return 0;
}
模闆參數範圍上,int ---- const int (比int小)
T到T*,縮小了
T到 T& T&& (右值引用)
2.函數模闆特化
2.1 函數模闆全特化
全特化函數模闆實際上等價于執行個體化 一個函數模闆,并不是等價于一個函數重載。
//void tfunc<int ,double>(int &,double &){} 全特化,等價于執行個體化一個函數模闆
//void tfunc (int &tmp1,double &temp2) {} 函數重載
#include <iostream>
#include <string>
using namespace std;
// 函數模闆泛化版本
template <typename T,typename U>
void tfunc(T &tmprv, U &tmprv2)
{
cout << "tfunc泛化版本!" << endl;
cout << tmprv << endl;
cout << tmprv2 << endl;
}
// 函數模闆全特化版本 T =int ,U = double
template <>
void tfunc(int &tmprv, double &tmprv2)
{
cout << "tfunc特化版本!<int, double>" << endl;
cout << tmprv << endl;
cout << tmprv2 << endl;
}
// 函數模闆重載函數
void tfunc(int &tmprv, double &tmprv2)
{
cout << "tfunc重載函數版本" << endl;
cout << tmprv << endl;
cout << tmprv2 << endl;
}
int main()
{
const char *p = "I Love China!";
int i = 12;
// 泛化版本
tfunc(p, i);
// 特化版本
int x = 1; double y = 3;
tfunc(x, y);
//編譯器選擇最合适的版本:普通函數 > 特化版本 > 泛化版本;
//全特化函數模闆實際等價于執行個體化一個函數模闆,并不是函數重載。
//void tfunc<int, double>(int &tmpv1, double &tmpv2){ }
//void tfucn(int &tmpv1, double &tmpv2) { }
system("pause");
return 0;
}
//編譯器選擇最合适:普通優先,特化版本,泛化版本
//數組類型模闆參數,比 指針類型模闆參數更合适。
如果你傳遞字元串給函數模闆,函數模闆的特化版本中有 數組類型模闆參數, 指針類型模闆參數。
編譯器會認為 數組類型模闆參數比指針類型模闆參數更合适。 是以編譯器會為你選擇數組類型的模闆參數 的特化版本。
2.2 函數模闆不能偏特化
寫法就沖突了:C++不支援函數模闆偏特化,隻能全特化。
3.模闆特化版本放置位置建議
模闆定義。實作都放在一個.h的檔案中
模闆的特化版本泛化版本,實作都放在同一個.h檔案中
.h檔案中前邊放泛化版本,後邊放特化版本。