全特化
全特化一般用于处理有特殊要求的类或者函数,此时的泛型模板无法处理这种情况。
#include <iostream>
#include <cstring>
using namespace std;
template<typename T>
class A {
public:
bool cmp(const T &t1, const T &t2) {
return t1 == t2;
}
};
template<>
class A<char*> { // 这里是全特化,仍然需要tempalte<>声明
public:
bool cmp(const char* t1, const char* t2) {
while(*t1 != '\0' && *t2 != '\0') {
if(*t1 != *t2) {
return false;
}
++t1;
++t2;
}
return true;
}
};
int main() {
A<int> cmp;
cout << cmp.cmp(1, 2) << endl;
char* c1 = "hello";
char* c2 = "hello";
A<char*>cmp1;
cout << cmp1.cmp(c1, c2);
return 0;
}
上述是一个类的全特化声明,这是一个比较类,但是==
比较的是C风格字符串的首地址,而我们需要比较两个C风格的字符字符串内容是否相等,所以进行一次全特化。
对于函数,也是用类似的操作:
#include <iostream>
#include <cstring>
using namespace std;
template<typename T1, typename T2>
bool cmp(T1 &t1, T2 &t2) {
return t1 == t2;
}
template<>
bool cmp(char* &p1, char* &p2) {
auto pt1 = p1, pt2 = p2;
while(*pt1 != '\0' && *pt2 != '\0') {
if(*pt1 != *pt2) {
return false;
}
++pt1;
++pt2;
}
return true;
}
int main() {
char* p1 = "test";
char* p2 = "test";
int a = 0, b = 1;
cout << cmp(a, b) << endl; // 0
cout << cmp(p1, p2) << endl; // 1
return 0;
}
偏特化
如果我们指向特别制定部分的类型,那么需要进行特化,还是以上述的模板为例子:
#include <iostream>
#include <cstring>
using namespace std;
template<typename T, typename T1>
class A {
public:
A() = default;
A(const T1& n) {
cout << n << endl;
}
bool cmp(const T &t1, const T &t2) {
return t1 == t2;
}
};
template<typename T1> // 片特化
class A<char*, T1> {
public:
A() = default;
A(T1& n) {
cout << n << endl;
}
bool cmp(const char* t1, const char* t2) {
while(*t1 != '\0' && *t2 != '\0') {
if(*t1 != *t2) {
return false;
}
++t1;
++t2;
}
return true;
}
};
int main() {
char* p1 = "hello";
char* p2 = "hello";
A<int, char*>c(p1);
cout << c.cmp(1, 2) << endl;
A<char*, char*>c1(p2); // 即使是片特化,也要全部声明模板
cout << c1.cmp(p1, p2) << endl;
return 0;
}
函数模板没有偏特化,因为有函数重载的概念,C++根据参数的类型来判断重载哪一个函数,如果还进行偏特化,这就与重载相冲突。但是,我们可一个对模板进行重载,从而实现偏特化。
template <typename T>
class C {...}; //此泛化版本的T可以是任何类型
template <typename T>
class C<T*> {...}; //特化版本,T为指针类型