C++ - 泛性编程类模板的特定实现

1.多参数类模板

类模板可以定义任意多个不同的类型参数:

函数模板也可以支持多个不同类型参数。 

使用类模板必须一一指定类型,函数模板可以不用。

2.类模板可以被特化

指定类模板的特定实现。

部分类型参数必须显示指定。

根据类型参数分开实现类模板。

特殊化为只接受一个类型(T1和T2类型相同)。在指定实际类型时,如果T1和T2类型相同,编译器会优先使用右边的模板。编译器会根据实际情况分析使用左边或者右边。编译器认为这两个模板是同一个,在使用的时候会根据参数进行选择使用。

部分特化 :用特定规则约束类型参数。

代码示例:第一种方式部分特化

template<typename T1>
class example<T1, char> //这里指定第二个模板参数为char
{
public:
    example();
    ~example();
private:
    T1 data1;
    char data2;
    int data3;
};

template<typename T1> //由于只指定了第二个模板参数的类型,所以这里还有给出模板形参T1
example<T1, char>::example()
    :data1(3),
    data2(3),
    data3(3)
{
    cout << "偏特化<T1, char>实例构造完成" <<endl;
}

template<typename T1>
example<T1, char>::~example()
{
    cout << "偏特化<T1, char>实例析构完成" <<endl;
}

代码示例:第二种方式部分特化

template<typename T1, typename T2>
class example<T1 *, T2 *> //这里特化为两模板参数为指针版本
{           //当实例化对象时,若指定的模板参数为两指针,则会通过此来进行实例化
public:
    example();
    ~example();
private:
    T1 data1; //对于data1和data2而言,它们只关心实例化时传入指针解引用后的类型
    T2 data2;
    int data3;
    T1 * data4; //对于data4和data5而言,它们关心实例化时传入的指针
    T2 * data5;
};

template<typename T1, typename T2> //对于编译器而言
                            //模板的类型仍是未知的,所以需要给出T1、T2两个模板参数
example<T1 *, T2 *>::example()
    :data1(0),
    data2(0),
    data3(0),
    data4(&data1),
    data5(&data2)
{
    cout << "构造<T1 *, T2 *>" << endl;
}

template<typename T1, typename T2>
example<T1 *, T2 *>::~example()
{
    cout << "析构<T1 *, T2 *>" << endl;
}

完全特化 :完全显示指定类型参数。

代码示例:

template<>     //C++语法规定,此处加template<>是为了说明正在定义一个特例化版本
class example<int, char> //此处尖括号内的内容说明模板参数为int、char
{
public:
    example();
    ~example();
private:
    int data1;
    char data2;
    int data3;
};
//由于已经指定了模板参数,所以这里不用给出模板形参
example<int, char>::example()
    :data1(2),
    data2(2),
    data3(2)
{
    cout << "构造完成全特化<int, char>的类模板实例" << endl;
}
example<int, char>::~example()
{
    cout << "析构完成全特化<int, char>的类模板实例" << endl;
}

3.特化的深入理解

代码示例:函数模板特化

#include <iostream>
#include <string>
 
using namespace std;
 
template
< typename T >
bool Equal(T a, T b)    //函数模板
{
    cout << "bool Equal(T a, T b)" << endl;
    
    return a == b;    //不能用来比较两个浮点数相等。解决办法:函数模板特化
}
 
template    //函数模板完全特化——显示声明
< >
bool Equal<double>(double a, double b)    //浮点数精度不够。完全特化
{
    const double delta = 0.00000000000001;
    double r = a - b;
    
    cout << "bool Equal<double>(double a, double b)" << endl;
    
    return (-delta < r) && (r < delta);    //用这种方式判断两个数相等
}
 
int main()
{  
    cout << Equal( 1, 1 ) << endl;    //函数模板
    cout << Equal<double>( 0.001, 0.001 ) << endl;
 
    return 0;
}

结果:

bool Equal(T a, T b)
1
bool Equal<double>(double a, double b)
1

定义重载函数:

#include <iostream>
#include <string>
 
using namespace std;
 
template
< typename T >
bool Equal(T a, T b)    //函数模板
{
    cout << "bool Equal(T a, T b)" << endl;
    
    return a == b;    //不能用来比较两个浮点数相等。解决办法:函数模板特化
}
 
template    //函数模板完全特化——显示声明
< >
bool Equal<double>(double a, double b)    //浮点数精度不够。完全特化
{
    const double delta = 0.00000000000001;
    double r = a - b;
    
    cout << "bool Equal<double>(double a, double b)" << endl;
    
    return (-delta < r) && (r < delta);    //用这种方式判断两个数相等
}
 
bool Equal(double a, double b)    //函数
{
    const double delta = 0.00000000000001;
    double r = a - b;
    
    cout << "bool Equal(double a, double b)" << endl;
    
    return (-delta < r) && (r < delta);
}
 
int main()
{  
    cout << Equal( 1, 1 ) << endl;    //函数模板
    cout << Equal( 0.001, 0.001 ) << endl;  
    return 0;
}

结果:

bool Equal(T a, T b)
1
bool Equal(double a, double b)
1

分析:

同名的特化函数和重载函数,会优先使用重载函数。

代码示例:如果一定要使用特化函数,要加上加上<>。

int main()
{  
    cout << Equal( 1, 1 ) << endl;    //函数模板
    cout << Equal<>( 0.001, 0.001 ) << endl;  //加上<>,让编译器先匹配特化
    return 0;
}

结果:

bool Equal(T a, T b)
1
bool Equal<double>(double a, double b)
1

4.工程中的建议(编码原则)

-> 当需要重载函数模板时,优先考虑实验模板特化;   

-> 当模板特化无法满足需求,再使用函数重载!

小结:

-> 类模板可以定义任意多个不同的类型参数。

-> 类模板可以被部分特化和完全特化。

-> 特化的本质是模板的分开实现。

-> 函数模板只支持完全特化。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式_笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值