模板的完全特例化和非完全特例化
大约 3 分钟
模板的完全特例化和非完全特例化
有完全特例化,就选择对应的,有部分特例化,就匹配,没有的话,就
template<typename T>
bool compare(T a, T b) {
cout << "template compare" << endl;
return a > b;
}
int main() {
compare(10, 20);
compare("aaa", "bbb"); //T const char*
return 0;
}
能运用在int类型上,字符串比较就不行了。 此时的实例化compare代码就不行了,。
需要多加一个模板的完全特例化:(完全特例化: 类型完全是已知的)
模板的完全特化
template后面的<>什么参数都没有,表示参数都是已知的。
template<>
bool compare<const char*>(const char* a, const char* b) {
cout << "compare<const char*>" << endl;
return strcmp(a, b) > 0;
}
模板的部分特例化
#include <iostream>
#include <cstdio>
using namespace std;
template<typename T>
class Vector
{
public:
Vector() { cout << "call Vector template init" << endl; }
};
//下面这个是对char*类型提供的完全特例化版本 #1
template<>//特例化的语法
class Vector<char*>
{
public:
Vector() { cout << "call Vector<char*> init" << endl; }
};
//下面这个是对指针类a型提供的部分特例化版本 #2
template<typename Ty>
class Vector<Ty*>
{
public:
Vector() { cout << "call Vector<Ty*> init" << endl; }
};
//指针函数指针(有返回值,有两个形参变量)提供的部分特例化
template<typename R, typename A1, typename A2>
class Vector<R(*)(A1, A2)>
{
public:
Vector() { cout << "call Vector<R(*)(A1, A2)> init" << endl; }
};
//针对函数(有一个返回值,有两个形参变量)类型提供的部分特例化
template<typename R, typename A1, typename A2>
class Vector<R(A1, A2)>
{
public:
Vector() { cout << "call Vector<R(A1, A2)> init" << endl; }
};
int sum(int a, int b) { return a + b; }
int main()
{
Vector<int> vec1;
Vector<char*> vec2;
Vector<int*> vec3;
Vector<int(*)(int, int)> vec4;
Vector<int(int, int)> vec5;//function
//注意区分一下函数类型和函数指针类型
//用函数指针定义的变量本身就是一个指针
typedef int(*PFUNC1)(int, int); //PFUNC1是函数指针类型
PFUNC1 pfunc1 = sum;
cout << pfunc1(10, 20) << endl;
typedef int PFUNC2(int, int); //PFUNC2是函数类型
//函数类型在定义的时候,需要将指针*加上
PFUNC2* pfunc2 = sum;
cout << (*pfunc2)(10, 20) << endl;
return 0;
}
模板的实参推演
//T包含了所有的大的类型 返回值,所有形参的类型都取出来
tempalte<typename T>
void func(T a) {
cout << typeid(T).name() << endl;
}
int sum(int a, int b) { return a + b;}
int main() {
func(10); //int
func("aaa"); //const char *
func(sum); //T int (*)(int, int) int (int, int)
}
我们,我们直接用一个函数指针的模板部分特例化来做:
template<typename R, typename A1, typename A2>
void fun2(R(*a)(A1, A2)) {
cout << typeid(R).name() << endl; //int
cout << typeid(A1).name() << endl; //int
cout << typeid(A2).name() << endl; //int
}
fun2(sum);
定义一个Test类,里面有一个成员函数sum
class Test {
public:
int sum(int a, int b) { return a + b; }
};
template <typename T>
void func(T a) {
cout << typeid(T).name << endl;
}
int main() {
func(&Test::sum); //int (__thiscall Test::*)(int, int)
}
得到一个指向成员方法的函数指针类型。将其参数细分:
template<typename R, typename T, typename A1, typename A2>
void func3(R(T::* a)(A1, A2)) {
cout <<typeid(R).name() <<endl; //int
cout <<typeid(T).name() <<endl; //class Test
cout <<typeid(A1).name() <<endl; //int
cout <<typeid(A2).name() <<endl; //int
}
总结
这几个例子指导我们在写函数模板,类模板时,针对一个具体情况,把他们一个大类型的细分类型,定义相应的参数,接收大类型的所有细分类型,使用的就是模板部分偏特化。