显示具体化
首先在.h头文件定义个类模板,如下
#pragma once
#include <iostream>
//通用模板类型
template<class T1, class T2>
class AA
{
public:
void print();
};
template<class T1, class T2>
void AA<T1, T2>::print() {
std::cout << "template<class T1, class T2>" << std::endl;
}
显示具体化是特定类型的定义。有时候,可能需要在为特殊类型实例化时,对模板进行修改,使其行为不同。在这种情况下,可以创建显示具体化,例如,上面定义的类模板AA,想在两个类型参数都为int时,print函数输出”template<>”。这种情况下,可以为通用模板指定具体类型,当具体化模板和通用模板都与实例化请求匹配时,编译器将选择具体化版本。
具体化类模板定义格式为:template<>class 类名<具体类型>
具体化是将通用模板具体化,因此必须要有通用模板存在才可以使用具体化,否则单独使用会报错。上述类模板具体化int类型后,.h的内容如下
#pragma once
#include <iostream>
//通用模板类型
template<class T1, class T2>
class AA
{
public:
void print();
};
template<class T1, class T2>
void AA<T1, T2>::print() {
std::cout << "template<class T1, class T2>" << std::endl;
}
//具体化:给出确定的模板类型参数
template<>
class AA<int, int>
{
public:
void print();
};
//显示具体化,不需要加template<>
void AA<int, int>::print() {
std::cout << "template<>" << std::endl;
}
这样AA在两个参数都使用int类型时,会优先匹配具体化int型的模板;在使用其他类型时会匹配泛型模板。主函数代码如下
int main()
{
//匹配通用模板
AA<char, int> a1;
a1.print();
//匹配显示具体化
AA<int, int> a2;
a2.print();
system("pause");
return 0;
}
输出为
template<class T1, class T2>
template<>
从结果看出,a1只与通用类模板匹配,所以打印通用类模板print的内容;a2与两个模板都匹配,但与显示具体化的匹配程度最高,所以输出其print内容。
部分具体化
C++还允许部分具体化,给部分类型参数制定具体类型,部分参数类型为通用类型。如下
//通用类模板
template<class T1, class T2>
class AA{};
//部分具体化类模板
template<class T1>
class AA<T1, int>{};
关键字template后面的<>声明的是没有被具体化的类型参数。因此,上述第二个声明将T2具体化为int,但T1保持不变。注意,如果指定所有的类型参数,将导致<>为空,也就是显示具体化,.h内容如下
#pragma once
#include <iostream>
//通用模板类型
template<class T1, class T2>
class AA
{
public:
void print();
};
template<class T1, class T2>
void AA<T1, T2>::print() {
std::cout << "template<class T1, class T2>" << std::endl;
}
//具体化:给出确定的模板类型参数
template<>
class AA<int, int>
{
public:
void print();
};
//具体化:给出确定的模板类型参数
void AA<int, int>::print() {
std::cout << "template<>" << std::endl;
}
//部分具体化:具体化一个或多个参数类型,模板参数列表中放未具体化类型
//定义对象时会根据参数类型优先使用具体化的类型
template<class T1>
class AA<T1, int>
{
public:
void print();
};
template<class T1>
void AA<T1, int>::print() {
std::cout << "template<class T1, int>" << std::endl;
}
如果有多个模板可供选择,编译器将使用具体化度最高的模板,主函数代码如下
int main()
{
//匹配通用模板
AA<char, char> a1;
a1.print();
//匹配显示具体化
AA<int, int> a2;
a2.print();
//部分具体化
AA<char, int> a3;
a3.print();
system("pause");
return 0;
}
输出为
template<class T1, class T2>
template<>
template<class T1, int>
从结果看出,a1只与通用类模板匹配,所以打印通用类模板print的内容;a2与三个模板都匹配,但与显示具体化的匹配度最高,所以输出其print内容;a3与通用类模板和部分具体化类模板都匹配,但与部分具体化的匹配度最高,所以输出其print内容。
注意:显示具体化与部分具体化和通用类模板不同,它是一个具体的类会生成类的定义,其他两个只是生成类的方案。在类模板的显示具体化中,成员函数的实例化是不能带模板头template<>的。