本文共 2656 字,大约阅读时间需要 8 分钟。
“泛型编程”:一种不考虑具体数据类型的编程方式
假如现在有个需求,我们要实现一些类,主要用于存储和组织数据结构(如链表类、堆类等),关注其实现的裸机,而不是数据结构中元素的具体类型
template //类模板一般在头文件里定义,template关键字告诉编译器开始泛型编程,< typename T1, typename T2, int N>//typename关键字用于声明泛指类型class Operator{public: T1 add(T2 a, N)//模板的预处理阶段可以传入参数,只能传递常量,有点类似于宏定义,N就是一个参数};template //template关键字告诉编译器开始泛型编程< typename T1, typename T2, int N>//如果成员函数在外面定义,则也要加template和typename T1 Operator::add(T2 a, N){ return static_cast (a + b);}int main(){ Operator op1; //实例化类时,必须显示指定类型 op1.add(1, 2); //调用类中的成员函数 return 0;}
template//原模板< typename T1, typename T2 >class Test{public: void add(T1 a, T2 b) { cout << "void add(T1 a, T2 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; } void print()//也可以新增原模板的函数 { }};template< >class Test < void*, void* > //完全特化,当参数都为void*时优先调用{public: void add(void* a, void* b) { cout << "void add(void* a, void* b)" << endl; }};int main(){ Testt1;//调用原模板 Test t2;//调用部分特化的模板 Test t3;//调用完全特化的模板 return 0;}
假设现在有个需求,需要我们实现一个Add接口,该接口可以对两个类型(int、double、string等都有可能)的变量进行相加,并将结果强制类型转换为特定类型再回
template //template关键字告诉编译器开始泛型编程< typename T1, typename T2, typename T3>//typename关键字用于声明泛指类型T1 Add(T2 a, T3 b){ return static_cast(a + b);}
template//Add函数模板的一个完全特化< >char Add(int a, float b){ cout << "123" << endl;//特化的函数模板可以和原模板不一样 return static_cast(a + b);}
template < typename T1, typename T2, typename T3>
中的顺序一一对应,工程中一般将第一个类型作为返回值类型int a = 1;float b = 0;char c = Add(b, a);//调用原模板,自动推导参数类型,但是无法推导返回值的类型char d = Add(a, b);//调用完全特化模板,显式指明类型为T1为char,T2为int,T3为float,char d = Add (a, b);//当然,也可以偷个懒,只指明返回值类型为char,反正参数类型可以自动推导....
函数模板也能被重载,不过只根据参数的个数不同来重载罢了,并且工程中,一般只是特化函数模板,并不会去重载函数模板。那么当一个普通的函数及其重载函数,遇到一个同名的函数模板及其特化时,编译器优先调用谁?
Add<>(a, b)
来指定编译器调用函数模板转载地址:http://lpvin.baihongyu.com/