网站开发维护成本cps网站建设
- 作者: 五速梦信息网
- 时间: 2026年03月21日 07:35
当前位置: 首页 > news >正文
网站开发维护成本,cps网站建设,seo积分系统,个人网站建设教学视频目录
- 模板概念
- 函数模板语法
- 函数模板注意事项
- 函数模板案例
- 普通函数与函数模板的区别
- 普通函数与函数模板的调用规则
- 模板的局限性 1. 模板概念 在C中#xff0c;模板是一种通用的程序设计工具#xff0c;它允许我们处理多种数据类型而不是固…目录
- 模板概念 2. 函数模板语法
- 函数模板注意事项
- 函数模板案例 5. 普通函数与函数模板的区别
- 普通函数与函数模板的调用规则
7. 模板的局限性 1. 模板概念
在C中模板是一种通用的程序设计工具它允许我们处理多种数据类型而不是固定的一种。函数模板就是其中之一它使得我们可以编写一个函数来处理不同类型的数据。
模板的特点 模板不可以直接使用它只是一个框架必须确定出T的类型第3章有讲 模板的通用并不是万能的
2. 函数模板语法 C提供两种模板机制:函数模板和类模板 。为避免文章冗长本文先介绍函数模板下一篇文章介绍类模板。 函数模板作用建立一个通用函数其函数返回值类型和形参类型可以不具体制定用一个虚拟的类型来代表。 使用语法 templatetypename T 或者 templateclass T templatetypename T表示声明一个模板typename T是模板参数 typename —— 表面其后面的符号是一种数据类型可以用class代替。 个人习惯用templatetypename T代表函数模板templateclass T代表类模板。 T —— 通用的数据类型名称可以替换通常为大写字母T。 示例 //交换整型函数 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; } 函数模板利用关键字 template 使用函数模板有两种方式1、自动类型推导 2、显示指定类型 模板的目的是为了提高复用性将类型参数化
- 函数模板注意事项 自动类型推导的限制当使用自动类型推导时编译器需要根据函数参数类型推导出一致的数据类型 T 才能成功实例化模板函数。如果无法推导出一致的类型将导致编译错误。 // 示例代码 templatetypename T void myFunction(T arg1, T arg2) {// 函数体 }int main() {myFunction(10, 20); // 正确推导出一致的 int 类型myFunction(10, 20.5); // 错误无法推导出一致的类型return 0; }模板参数的确定在模板函数调用时必须要确定模板参数的数据类型否则编译器无法生成对应的函数实例。 // 2、模板必须要确定出T的数据类型才可以使用 templateclass T void func() {cout func 调用 endl; }void test01() {//func(); //错误模板不能独立使用必须确定出T的类型funcint(); //利用显示指定类型的方式给T一个类型才可以使用该模板 }funint()代表对模板函数 fun 进行实例化并指定模板参数 T 的具体类型为 int。在这种情况下编译器会生成一个针对 T 为 int 类型的具体函数实现。其效果就好比是将模板中的 T 替换为 int然后使用 int 类型的函数来处理相应的逻辑。
- 函数模板案例
案例描述 利用函数模板封装一个排序的函数可以对不同数据类型数组进行排序 排序规则从大到小排序算法为选择排序 分别利用char数组和int数组进行测试
//交换的函数模板 templatetypename T void mySwap(T a, Tb) {T temp a;a b;b temp; }templatetypename T // 也可以替换成class //利用选择排序进行对数组从大到小的排序 void mySort(T arr[], int len) {for (int i 0; i len; i){int max i; //最大数的下标for (int j i 1; j len; j){if (arr[max] arr[j]){max j;}}if (max ! i) //如果最大数的下标不是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[] bdcfeagh;int num sizeof(charArr) / sizeof(char);mySort(charArr, num);printArray(charArr, num); }void test02() {//测试int数组int intArr[] { 7, 5, 8, 1, 3, 9, 2, 4, 6 };int num sizeof(intArr) / sizeof(int);mySort(intArr, num);printArray(intArr, num); }int main() {test01();test02();system(pause);return 0; } 5. 普通函数与函数模板的区别 普通函数与函数模板区别 普通函数调用时可以发生自动类型转换隐式类型转换 函数模板调用时如果利用自动类型推导不会发生隐式类型转换 如果利用显示指定类型的方式可以发生隐式类型转换
示例 // 普通函数和函数模板的区别// 1、普通函数调用可以发生隐式类型转换 // 2、函数模板用 自动类型推导时不可以发生隐式类型转换 // 3、函数模板用 显示指定类型时 可以发生隐式类型转换// 普通函数 int myAdd01(int a, int b) {return a b; }// 模板函数 templatetypename T T myAdd02(T a, T b) {return a b; }void test01() {int a 10;int b 20;char c c;cout 普通函数int a int b myAdd01(a, b) endl;// 普通函数中隐式的将c转成了ASSIC码c-99cout 普通函数int a char c myAdd01(a, c) endl;// 自动类型推导// 会报错模板函数自动类型推导时不会发生隐式类型转换// cout 模板函数int a char c myAdd02(a, c) endl;// 显示指定类型cout 模板函数int a char c myAdd02int(a, c) endl; }int main() {test01(); } 6. 普通函数与函数模板的调用规则 调用规则如下 如果函数模板和普通函数都可以实现优先调用普通函数 可以通过空模板参数列表来强制调用函数模板 函数模板也可以发生重载 如果函数模板可以产生更好的匹配,优先调用函数模板
//普通函数与函数模板调用规则 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; } 既然提供了函数模板最好就不要提供普通函数否则容易出现二义性。 7. 模板的局限性 例如 templateclass Tvoid f(T a, T b){ a b;} 如果数据类型是int型此时的赋值操作没问题。如果传入的a和b是一个数组就无法实现了。 再例如 templateclass Tvoid f(T a, T b){ if(a b) { … }} 如果T的数据类型传入的是像Person这样的自定义数据类型也无法正常运行。 因此C为了解决这种问题提供模板的重载可以为这些特定的类型提供具体化的模板 #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; } 在这个特定的例子中通用的函数模板 myCompare 用于比较两个对象是否相等但是当对象类型是 Person 类型时我们想要做一些特殊的比较比如比较 Person 类的 m_Name 和 m_Age 成员变量。为了实现这一目的我们对通用模板进行了具体化。 具体化的语法是在 template 关键字后面指定特定的类型这里是 Person然后是模板的原型即函数签名 bool myCompare(Person p1, Person p2)。在函数体中我们以特定方式实现了 Person 类型对象的比较逻辑即比较它们的名字和年龄。 当在代码中调用 myCompare 函数并传递 Person 类型的参数时编译器会优先选择这个具体化版本而不是通用的模板版本。 总结 利用具体化的模板可以解决自定义类型的通用化 学习模板并不是为了写模板而是在STL能够运用系统提供的模板
相关文章
-
网站开发微信小程序需求量大吗长沙手机网站制作
网站开发微信小程序需求量大吗长沙手机网站制作
- 技术栈
- 2026年03月21日
-
网站开发微信提现功能电脑上自己做科目一的网站
网站开发微信提现功能电脑上自己做科目一的网站
- 技术栈
- 2026年03月21日
-
网站开发网站源码怎么搞到网站
网站开发网站源码怎么搞到网站
- 技术栈
- 2026年03月21日
-
网站开发维护岗位职责邮箱怎么上传wordpress
网站开发维护岗位职责邮箱怎么上传wordpress
- 技术栈
- 2026年03月21日
-
网站开发维护面试微信小程序商城开发教程
网站开发维护面试微信小程序商城开发教程
- 技术栈
- 2026年03月21日
-
网站开发维护企业网站服务器多少钱
网站开发维护企业网站服务器多少钱
- 技术栈
- 2026年03月21日
