第五十九课、类模板的深度剖析

一、多参数的类模板

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

2、类模板可以被特化

(1)、指定类模板的特定实现

(2)、部分类型参数必须显示指定(如class Test<T, T> 就是现实指定T)

(3)、根据类型参数分开实现类模板(同一个模板根据需要用不同方式来实现而已)

(4)、类模板的特化类型

A、部分特化:用特定规则约定类型参数(仍然存在类型参数

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

(5)、特化注意事项

A、特化只是模板的分开实现(实现的功能都一样,本质上还是同一个模板,根据需要使用不同的实现方式而已)
B、特化类模板的使用方式是统一的(定义对象时必须显示指定每一个参数的类型

 

#include <iostream>
#include <string>

using namespace std;

template
< typename T1, typename T2 >
class Test
{
public:
    void add(T1 a, T2 b)
    {
        cout << "void add(T1 a, T2 b)" << endl;
        cout << a + b << endl;
    }
};

template
< typename T1, typename T2 >  //部分特化,因为还有类型参数
class Test < T1*, T2* >      // 关于指针的特化实现,特化时在这里显示指定参数的类型,如这里的< T1*, T2*>
{               // 用以实现上述模板的特殊情况,本质上还是同一个模板 public: void add(T1* a, T2* b) { cout << "void add(T1* a, T2* b)" << endl; cout << *a + *b << endl; } }; template < typename T >//部分特化 class Test < T, T > // 当 Test 类模板的两个类型参数完全相同时,使用这个实现 { public: void add(T a, T b) { cout << "void add(T a, T b)" << endl; cout << a + b << endl; } void print()//特化类可以有自己的成员函数 { cout << "class Test < T, T >" << endl; } }; template < >//完全特化 class Test < void*, void* > // 当 T1 == void* 并且 T2 == void* 时 { public: void add(void* a, void* b) { cout << "void add(void* a, void* b)" << endl; cout << "Error to add void* param..." << endl; } }; int main() { Test<int, float> t1; Test<long, long> t2;//选择参数相同的特化类模板 Test<void*, void*> t3;//选择void*时的特化类模板(优先于两个参数相同的那个) t1.add(1, 2.5); t2.add(5, 5); t2.print(); t3.add(NULL, NULL); Test<int*, double*> t4;//选择指针时的版本 int a = 1; double b = 0.1; t4.add(&a, &b); return 0; } //输出结果 /* void add(T1 a, T2 b) 3.5 void add(T a, T b) 10 class Test < T, T > void add(void* a, void* b) Error to add void* param... void add(T1* a, T2* b) 1.1 */

 

二、特化与重定义的区别

1、重定义

(1)、一个类模板和一个新类(或者两个类模板)

(2)、使用的时候需要考虑如何选择的问题

2、特化

(1)、以统一的方式使用类模板和特化类(定义对象是显示指定参数

(2)、编译器自动优先选择特化类

(3)、函数模板的特化(只能完全特化)

3、工程中的建议

(1)、当需要重载函数模板时,优先考虑使用模板特化

(2)、当特化无法满足需求时,再考虑函数模板

#include <iostream>
#include <string>

using namespace std;

template
< typename T1, typename T2 >
class Test
{
public:
    void add(T1 a, T2 b)
    {
        cout << "void add(T1 a, T2 b)" << endl;
        cout << a + b << endl;
    }
};

template
< typename T1, typename T2 >
class Test < T1*, T2* >      // 关于指针的特化实现
{
public:
    void add(T1* a, T2* b)
    {
        cout << "void add(T1* a, T2* b)" << endl;
        cout << *a + *b << endl;
    }
};

template
< typename T >
class Test < T, T >    // 当 Test 类模板的两个类型参数完全相同时,使用这个实现
{
public:
    void add(T a, T b)
    {
        cout << "void add(T a, T b)" << endl;
        cout << a + b << endl;
    }
    void print()
    {
        cout << "class Test < T, T >" << endl;
    }
};
/*
template
<  >
class Test < void*, void* >    // 当 T1 == void* 并且 T2 == void* 时
{
public:
    void add(void* a, void* b)
    {
        cout << "void add(void* a, void* b)" << endl;
        cout << "Error to add void* param..." << endl;
    }
};
*/

//类模板的重定义,本质上已经是一个新的类 class Test_void { public: void add(void* a, void* b) { cout << "void add(void* a, void* b)" << endl; cout << "Error to add void* param..." << endl; } };
/************************ 函数 *******************************/ 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) { cout << "bool Equal(double a, T double)" << endl; const double delta = 0.00000000000001; double r = a - b; return (-delta < r) && (r < delta); } //函数重定义 bool Equal(double a, double b) { const double delta = 0.00000000000001; double r = a - b; return (-delta < r) && (r < delta); } int main() { //Test<void*, void*> t3; Test_void t3; t3.add(NULL, NULL); cout << endl; cout << Equal<>(1.2, 0.6) << endl;//< > 限定编译器只匹配模板 return 0; }

四、小结

(1)、类模板可以定义任意多个类型不同的参数

(2)、类模板可以被部分特化完全特化

(3)、特化的本质模板的分开实现

(4)、函数模板只支持完全特化

(5)、工程中用模板特化代替类(函数)重定义

posted @ 2017-02-08 07:08  lgc202  阅读(289)  评论(0编辑  收藏  举报