2022-03-06 重载、模板、模板特例化、模板偏特例化区别

重载、模板、模板特例化、模板偏特例化区别

对于不同数据类型,采用不同处理 -- 重载

//交换 int 变量的值
void Swap(int *a, int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
}
//交换 float 变量的值
void Swap(float *a, float *b){
    float temp = *a;
    *a = *b;
    *b = temp;
}

对于不同数据类型,采用统一处理 -- 模板

template<typename T> void Swap(T &a, T &b){
    T temp = a;
    a = b;
    b = temp;
}

解决了“重载对于不同类型的复杂处理”的问题,但是存在一个问题,对于不同类型,统一处理会出问题,例如:int 类型的数据,判等可以直接用 ==,但是对于 float 类型,判等不能直接用 ==

对于不同数据类型,有统一处理,针对一些特殊类型,有特殊处理 -- 模板特例化

为了解决模板存在的问题,可以在已经有统一处理的基础上,再对特定数据类型,进行特例化:

#include <iostream>
using namespace std;

// 统一处理
template <class T>
class Compare
{
public:
     bool IsEqual(const T& arg, const T& arg1);
};

// 特例处理:已经不具有template的意思了,已经明确为float了
template <>
class Compare<float>
{
public:
     bool IsEqual(const float& arg, const float& arg1);
};
// 统一处理
template <class T>
bool Compare<T>::IsEqual(const T& arg, const T& arg1)
{
     cout<<"Call Compare<T>::IsEqual"<<endl;
     return (arg == arg1);
}
// 针对 float 类型的特例处理
bool Compare<float>::IsEqual(const float& arg, const float& arg1)
{
     cout<<"Call Compare<float>::IsEqual"<<endl;
     return (abs(arg - arg1) < 10e-3);
}


int main()
{
     Compare<int> obj;
     Compare<float> obj1;
     cout<<obj.IsEqual(2, 2)<<endl;
     cout<<obj1.IsEqual(2.003, 2.002)<<endl;
     return 0;
}

可以看到上面对 float 处理中,所有的数据类型都特例化为 float 了,不存在任何通用类型 T,即全特例化;而偏特例化,就是即含有特定数据类型 float,也有通用数据类型 T

template <class T2>
class A<int, T2>{
    ...
};

函数模板是不允许偏特化的,下面的声明会编译错:

template <class T1, class T2>
void f(){}

template <class T2>
void f<int, T2>(){}

但函数允许重载,声明另一个函数模板即可替代偏特化的需要:

template <class T2>
void f(){}              // 注意:这里没有"模板实参"

以上参考博文:

1

2

3

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容