外贸免费开发网站建设,长沙网站建设流程,重庆网站建设建站收费,稳定的网站服务器租用模板是泛型编程的基础#xff0c;泛型编程即以一种独立于任何特定类型的方式编写代码。模板的目的是为了提高复用性#xff0c;将类型参数化#xff0c;函数模板作用#xff1a;建立一个通用函数#xff0c;其函数返回值类型和形参类型可以不具体制定#xff0c;用一个虚…模板是泛型编程的基础泛型编程即以一种独立于任何特定类型的方式编写代码。模板的目的是为了提高复用性将类型参数化函数模板作用建立一个通用函数其函数返回值类型和形参类型可以不具体制定用一个虚拟的类型来代表。
例如
交换整形函数和交换浮点型函数在不使用模板的情况下需要定义两次函数但我们发现函数中除了函数名和变量类型外其他代码均相同。那有没有一种办法可以只定义一次函数实现这类型的交换函数呢答案是有用模板
templatetypename T//函数声明或定义
template --- 声明创建模板
typename --- 表面其后面的符号是一种数据类型可以用class代替
T --- 通用的数据类型名称可以替换通常为大写字母
#include iostream
using namespace std;//交换整型函数
void swapInt(int a, int b) {int temp a;a b;b temp;
}//交换浮点型函数
void swapDouble(double a, double b) {double temp a;a b;b temp;
}//利用模板提供通用的交换函数
templatetypename T
void mySwap(T a, T b)
{T temp a;a b;b temp;
}void test01()
{int a 10;int b 20;//swapInt(a, b);//利用模板实现交换//1、自动类型推导//mySwap(a, b);//2、显示指定类型mySwapint(a, b);cout a a endl;cout b b endl;}int main() {test01();system(pause);return 0;
} 在上述代码中模板函数mySwap可以使用两种方法完成数据类型的指定
1.自动类型推导
mySwap(a,b);
编译器根据我们传入的ab类型来确认数据类型
2.显示指定类型
mySwap数据类型(a,b);
注意事项1.自动类型推导必须推导出一致的数据类型T,才可以使用 2.模板必须要确定出T的数据类型才可以使用
案例
利用函数模板封装一个排序的函数可以对不同数据类型数组进行排序 排序规则从大到小排序算法为选择排序 分别利用char数组和int数组进行测试
#includeiostream
using namespace std;
templateclass T
//交换函数模板
void mySwap(T a, T b)
{T temp a;a b;b temp;
}
//排序算法
templateclass T
void mySort(T arr[],int len)
{for (int i 0; i len; i){int max i;//认定最大值下标for (int j i 1; j len; j){//认定的最大值 比遍历出的数值要小说明j下标的元素才是真正的最大值if (arr[max] arr[j]){max j;}}if (max ! i){//交换max和i元素mySwap(arr[max], arr[i]);}}
}//提供打印数组模板
templatetypename T
void printArray(T arr[], int len) {for (int i 0; i len; i) {cout arr[i] ;}cout endl;
}
void test01()
{//测试char数组char charArr[] badcfekb;int num sizeof(charArr) / sizeof(char);mySort(charArr, num);printArray(charArr, num);
}void test02()
{//测试int数组int intArr[] { 3,2,7,9,4,6,8,0 };int num sizeof(intArr) / sizeof(int);mySort(intArr, num);printArray(intArr, num);
}int main()
{test01();test02();system(pause);return 0;} 运行结果如下 说明我们写的模板可以对不同数据类型数组进行排序
普通函数和函数模板的区别 普通函数调用时可以发生自动类型转换隐式类型转换 函数模板调用时如果利用自动类型推导不会发生隐式类型转换 如果利用显示指定类型的方式可以发生隐式类型转换
隐式类型转换若参与运算量的类型不同则先转换成同一类型然后进行运算。
int和char类型的数据使用函数模板时
//普通函数
#includeiostream
using namespace std;
int myAdd01(int a, int b)
{return a b;
}//函数模板
templateclass T
T myAdd02(T a, T b)
{return a b;
}//使用函数模板时如果用自动类型推导不会发生自动类型转换,即隐式类型转换
void test01()
{int a 10;int b 20;char c c;//myAdd02(a, c); // 报错使用自动类型推导时不会发生隐式类型转换myAdd02int(a, c); //正确如果用显示指定类型可以发生隐式类型转换cout myAdd01(a, c) endl; //正确将char类型的c隐式转换为int类型 c 对应 ASCII码 99}int main() {test01();system(pause);return 0;
} 普通函数和函数模板的调用规则 1. 如果函数模板和普通函数都可以实现优先调用普通函数 2. 可以通过空模板参数列表来强制调用函数模板 3. 函数模板也可以发生重载 4. 如果函数模板可以产生更好的匹配,优先调用函数模板
#includeiostream
using namespace std;void myPrint(int a, int b)
{cout 调用的普通函数 endl;
}templatetypename T
void myPrint(T a, T b)
{cout 调用的模板 endl;
}templatetypename T
void myPrint(T a, T b, T c)
{cout 调用重载的模板 endl;
}void test01()
{//1、如果函数模板和普通函数都可以实现优先调用普通函数// 注意 如果告诉编译器 普通函数是有的但只是声明没有实现或者不在当前文件内实现就会报错找不到int a 10;int b 20;myPrint(a, b); //调用普通函数//2、可以通过空模板参数列表来强制调用函数模板myPrint(a, b); //调用函数模板//3、函数模板也可以发生重载int c 30;myPrint(a, b, c); //调用重载的函数模板//4、 如果函数模板可以产生更好的匹配,优先调用函数模板char c1 a;char c2 b;myPrint(c1, c2); //调用函数模板
}int main() {test01();system(pause);return 0;
} 模板的局限性 模板的通用性并不是万能的
templateclass T
void f(T a, T b)
{a b;
} 在上述代码中提供的赋值操作如果传入的a和b是一个数组就无法实现了 #includeiostream
using namespace std;#include stringclass Person
{
public:Person(string name, int age){this-m_Name name;this-m_Age age;}string m_Name;int m_Age;
};//普通函数模板
templateclass T
bool myCompare(T a, T b)
{if (a b){return true;}else{return false;}
}//具体化显示具体化的原型和定意思以template开头并通过名称来指出类型
//具体化优先于常规模板
template bool myCompare(Person p1, Person p2)
{if (p1.m_Name p2.m_Name p1.m_Age p2.m_Age){return true;}else{return false;}
}void test01()
{int a 10;int b 20;//内置数据类型可以直接使用通用的函数模板bool ret myCompare(a, b);if (ret){cout a b endl;}else{cout a ! b endl;}
}void test02()
{Person p1(Tom, 10);Person p2(Tom, 10);//自定义数据类型不会调用普通的函数模板//可以创建具体化的Person数据类型的模板用于特殊处理这个类型bool ret myCompare(p1, p2);if (ret){cout p1 p2 endl;}else{cout p1 ! p2 endl;}
}int main() {test01();test02();system(pause);return 0;
}
利用具体化的模板可以解决自定义类型的通用化如果不用具体化的模板系统软件将无法编译自定义类型