C++全特化与偏特化

全特化

全特化一般用于处理有特殊要求的类或者函数,此时的泛型模板无法处理这种情况。

#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为指针类型

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值