经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
函数模板
来源:cnblogs  作者:东南亚季风  时间:2021/1/11 9:57:45  对本文有异议

一、简介

在C++中,数据的类型也可以通过参数来传递,在函数定义时可以不指明具体的数据类型,当发生函数调用时,编译器可以根据传入的实参自动推断数据类型。这就是类型的参数化。

函数模板是一种特殊的函数,可以使用不同的类型进行调用,对于功能相同的函数,不需要重复编写代码,并且函数模板与普通函数看起来很类似,区别就是类型可以被参数化。

二、语法

函数模板的语法:

  1. template <typename 类型参数1 , typename 类型参数2 , ...> 返回值类型 函数名(形参列表){
  2. //在函数体中可以使用类型参数
  3. }

类型参数可以有多个,它们之间以逗号,分隔。类型参数列表以< >包围,形式参数列表以( )包围。

typename关键字也可以使用class关键字替代,它们没有任何区别。C++ 早期对模板的支持并不严谨,没有引入新的关键字,而是用 class 来指明类型参数,但是 class 关键字本来已经用在类的定义中了,这样做显得不太友好,所以后来 C++ 又引入了一个新的关键字 typename,专门用来定义类型参数。不过至今仍然有很多代码在使用 class 关键字,包括 C++ 标准库、一些开源程序等。

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <iostream>
  3. using namespace std;
  4. #if 0
  5. //int类型数据交换
  6. void MySwap(int& a, int& b){
  7. int temp = a;
  8. a = b;
  9. b = temp;
  10. }
  11. //double类型
  12. void MySwap(double& a, double& b){
  13. double temp = a;
  14. a = b;
  15. b = temp;
  16. }
  17. #endif
  18. //模板技术 类型参数化 编写代码可以忽略类型
  19. //为了让编译器区分是普通函数 模板函数
  20. template<class T1,class T2> //template<typename T>告诉编译器 ,下面写模板函数
  21. void MySwap(T& a, T& b){
  22. T temp = a;
  23. a = b;
  24. b = temp;
  25. }
  26. void test01(){
  27. int a = 30;
  28. int b = 20;
  29. //1 自动类型推导,编译器根据你传的值 进行类型自动推导
  30. cout << "a:" << a << " b:" << b << endl;
  31. MySwap(a, b);
  32. cout << "a:" << a << " b:" << b << endl;
  33. double da = 12.3;
  34. double db = 21.1;
  35. cout << "da:" << da << " db:" << db << endl;
  36. MySwap(da, db);
  37. cout << "da:" << da << " db:" << db << endl;
  38. //2. 显式的指定类型
  39. MySwap<int>(a, b);
  40. }
  41. int main(void){
  42. test01();
  43. return 0;
  44. }

三、函数模板跟普通函数

函数模板跟普通函数一样,也可以被重载

  • C++编译器优先考虑普通函数
  • 如果函数模板可以产生一个更好的匹配,那么就选择函数模板
  • 也可以通过空模板实参列表<>限定编译器只匹配函数模板
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <iostream>
  3. using namespace std;
  4. template<class T>
  5. int MyAdd(T a,T b){
  6. return a + b;
  7. }
  8. //普通函数可以进行自动类型转换
  9. //函数模板必须严格类型匹配
  10. int MyAdd(int a,int c){
  11. return a + c;
  12. }
  13. void test01(){
  14. int a = 10;
  15. int b = 20;
  16. char c1 = 'a';
  17. char c2 = 'b';
  18. MyAdd<>(a,b);//限定只使用函数模板
  19. MyAdd(a,c1);//这个调用,函数模板有更好的匹配,于是调用函数模板
  20. MyAdd(a, b);//普通函数int MyAdd(int a,int c)已经能完美匹配,于是调用普通函数
  21. MyAdd(c1,b);//这个调用,函数模板有更好的匹配,于是调用函数模板
  22. }
  23. //函数模板被重载
  24. template<class T>
  25. void Print(T a){
  26. }
  27. template<class T>
  28. void Print(T a , T b){
  29. }
  30. int main(void)
  31. {
  32. test01();
  33. return 0;
  34. }

四、函数模板机制:

  • 编译器并不是把函数模板处理成能够处理任何类型的函数
  • 函数模板通过具体类型产生不同的函数
  • 编译器会对函数模板进行再次编译,在声明的地方对模板代码本身进行编译,在调用的地方对参数替换后的代码进行编译。

原文链接:http://www.cnblogs.com/gqw-myblogs/p/14238569.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号