C++模板特化和偏特化

在介绍C++模板特化与偏特化之前,先简要回顾一下C++中的模板。

模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。模板是创建泛型类或函数的公式。
类模板
类模板定义的一般形式如下所示:

//模板类
template <typename T>
class class_name {
···
}

其中,T为类模板所要使用的数据类型占位符名称,这个名称可以在类的定义中使用。

下面是类模板的实例。

#include <vector>
#include <iostream>
#include <stdexcept>

template<typename T> 
class cQueue{
public:
    void push(T const& elem) { q.push_back(elem); }

    void pop() {
        if (q.empty()) return;
        q.pop_back();
    }
    
    T front(){
        if(q.empty()) throw out_of_range("empty queue");
        return q.front();
    }

    bool empty() const{ return q.empty();}
private:
    std::vector<T> q;
};

函数模板
函数模板定义如下所示:

#include <cstdlib>
#include <cstdio>
template <typename T>
T Max(const &T t1, const &T t2 ) {
    return t1 > t2 ? t1 : t2;
}

int main {
    float a=1.2;
    float b=2.0;
    printf("the max is %f\n", Max(a,b));
    return 0;
}

上面回顾了模板。可以看出,

如果是int/float/double类型的处理都是一样的处理,那么用上面介绍的模板类,或者模板函数就可以完美的解决。
如果增加对std::string类型或者char *的处理,且如果处理逻辑不一样呢,那是不是上面介绍的就不能解决了。
如果想把上面说的std::string问题解决,那就需要对std::string做特殊化处理,也就是特化。

特化分为全特化偏特化

全特化
将所有的类型参数全部明确指定。

偏特化
将部分类型参数明确指
定。

#include <cstdio>

template<typename T1, typename T2>
class Test{
public:
    Test(T1 x, T2 y):a(x),b(y){}
private:
    T1 a;
    T2 b;
}

template<> //全特化,所有的类型参数全部指定
class Test<int, char> {
    Test(int x, char y):a(x),b(y){}
private:
    int  a;
    char b;
}

template<typename T> //偏特化,部分类型参数指定
class Test<T, char> { 
    Test(T x, char y):a(x),b(y){}
private:
    T    a;
    char b;
}

上述讲的都是类模板的特化,没有提及到函数模板的特化,是因为模板特化版本不参与函数的重载抉策过程,因此在和函数重载一起使用的时候,可能出现不符合预期的结果。因此标准C++禁止了函数模板的偏特化。

而在实际的开发过程中,经常遇到需要函数的特化场景。那怎么办了?

具体可以参考下面的文章,提出的几种解决方案,其中第一种解决方案应该是最容易被我们接受,也最容易被我们想到,通过类模板的特化,来实现函数模板的特化。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值