目录
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;
}
特化成员函数而不是模板
#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文件中前边放泛化版本,后边放特化版本。