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

1.多参数类模板

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

C++ - 泛性编程类模板的特定实现_第1张图片

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

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

2.类模板可以被特化

指定类模板的特定实现。

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

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

C++ - 泛性编程类模板的特定实现_第2张图片

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

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

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

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

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

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

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

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

template
example::~example()
{
    cout << "析构" << endl;
}

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

代码示例:

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

3.特化的深入理解

代码示例:函数模板特化

#include 
#include 
 
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 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

定义重载函数:

#include 
#include 
 
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 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);    //用这种方式判断两个数相等
}
 
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 a, double b)
1

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

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

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

小结:

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

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

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

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

你可能感兴趣的:(C/C++,c++,算法,开发语言)