#include <iostream>
#include <string>
using namespace std;
template <typename T>
T Max(T a,T b){
return a>b?a:b;
}
int main(){
//指定类型
cout << Max<int>(10,13) << endl;
cout << Max<float>(10.01F,10.1F) << endl; //浮点型须显示指定为float,否则为double
cout << Max<double>(10.01,10.1) << endl;
cout << Max<string>(string("abc"),string("def")) << endl;
cout << Max<string>("abc","def") << endl;
//自动推导
cout << Max(10,13) << endl;
cout << Max(10.01F,10.1F) << endl;
cout << Max(10.01,10.1) << endl;
cout << Max(string("abc"),string("def")) << endl;
cout << Max("abc","def") << endl;
}
#include <stdlib.h>
#include <iostream>
#include <string>
using namespace std;
template <typename T> //定义模板类
class Array{
T* data;
int length;
public:
Array():data(NULL),length(0){}
~Array(){
delete [] data;
data = NULL;
length = 0;
}
void push_back(T val){
++length;
T* temp = new T[length]; //创建新的空间,再一一赋值,最后交换指针
for(int i=0;i<length-1;i++){
temp[i] = data[i];
}
temp[length-1] = val; //最后一个值赋值
delete [] data;
data = temp;
}
T& at(int index){
return data[index];
}
int size(){
return length;
}
T& operator[](int i){
return data[i];
}
const T& operator[](int i)const{
return data[i];
}
};
void TestInt(){ //测试整形
Array<int> arr;
arr.push_back(1);
arr.push_back(2);
arr.push_back(3);
for(int i=0;i<arr.size();i++){
cout << arr[i] << endl;
}
}
void TestString(){ //测试字符串
Array<string> arr;
arr.push_back("Hello");
arr.push_back("Hello2");
arr.push_back("Hello3");
for(int i=0;i<arr.size();i++){
cout << arr[i] << endl;
}
}
template <typename T> //在模板类的基础上定义一个模板函数
void Test(const Array<T>& arr){ //目的为减少重复代码,为各种类型提供一个模板,提高效率
for(int i=0;i<arr.size();i++){
cout << arr[i] << endl;
}
int main(){
TestInt();
TestString();
{
Array<int> arr;
arr.push_back(1);
arr.push_back(2);
arr.push_back(3);
Test(arr)
}
{
Array<string> arr;
arr.push_back("Hello");
arr.push_back("Hello2");
arr.push_back("Hello3");
Test(arr)
}
}
非类型形参
#include <iostream>
#include <string>
using namespace std;
template<typename T,int n> //这里的int n就是非类型形参
void show(T m){
if(n==1)
cout << oct << m <<endl;
else if(n==2)
cout << dec << m <<endl;
else
cout << hex << m <<endl;
}
template <typename T,int n>
void PrintArr(T (&arr)[n]){ //特殊用法,用了一个静态数组的引用,会自
for(int i=0;i<n;i++){ //动推导其大小和类型
cout << arr[i] << " ";
}
cout << endl;
}
int main() {
show<int,1>(100);
show<int,2>(100);
show<int,3>(100);
float arr[] = {1,2,3,4,5};
PrintArr(arr); //自动推导其大小和类型
}
如果类模板的成员函数在模板外实现,通常也需要写在头文件中,而不是写在源文件中
特化(对号入座相应的模板)示例:
#include <iostream>
using namespace std;
template<typename T> //原本类型为比较两个引用类型,但是当传入
const T& Max(const T& a,const T& b){ //两个指针类型时就不会比较解引用的值,而是
return a>b?a:b; //比较两个地址值的大小
}
template<typename T>
const T* Max(const T* a,const T* b){ //于是特化为指针类型
return *a > *b?a:b;
}
template<typename T>
const char* Max(const char* a,const char* b){ //特化为字符数组类型
return strcmp(a,b)>0?a:b;
}
int main(){
int a = 25;
int b = 20;
cout << *Max(&a,&b) << endl; //Max<int>(int*,int*)
const char* str = "abcd";
cout << *Max(str,str+1) << endl; //Max<char>(char*,char*)
}
示例:
#include <iostream>
#include <cstring>
using namespace std;
//引用类型模板
template <typename T>
bool Equal(const T& a,const T& b){
return a == b;
}
//特化成浮点型
template<>
bool Equal(const double& a,const double& b){
return abs(a-b) < 1e-6;
}
//--------------------------------------
//指针类型模板(函数模板重载)
template <typename T>
bool Equal(const T* a,const T* b){
return *a==*b;
}
//特化成char*
template <>
bool Equal(const char* a,const char* b){
return strcmp(a,b)==0;
}
int main(){
cout << Equal(1,1) << endl;
cout << Equal(1.2,1.2) << endl;
cout << Equal(string("abc"),string("abc")) <<endl;
cout << Equal(1,2) << endl;
cout << Equal(1.2,1.21) << endl;
cout << Equal(string("abcd"),string("abc")) << endl;
cout << Equal(1.2,(10.2-9)) << endl;
int arr[] = {1,2,3,1};
cout << Equal(arr,arr+3) << endl;
cout << Equal("abc","abcd") << endl;
}
#include <iostream>
#include <string>
using namespace std;
template<typename T,typename S,typename U>
class Triple{ //元组的元素类型可以是不同的
T t; //数组的元素类型必须是相同的
S s;
U u;
public:
Triple(T t,S s,U u):t(t),s(s),u(u){}
T& first(){return t;}
S& second(){return s;}
U& third(){return u;}
};
template<> //类模板特化(全特化)
class Triple<string,bool,int>{
string t;
bool s;
int u;
public:
Triple(string t,bool s,int u):t(t),s(s),u(u){
cout << "template<string,bool,int>" << endl;
}
string& first(){return t;}
bool& second(){return s;}
int& third(){return u;}
};
int main(){
Triple<string,bool,int> st("zhangsan",1,24);
cout << st.first() << st.second() << st.third() <<endl;
}