博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++学习之模板(一) ----函数模板
阅读量:4582 次
发布时间:2019-06-09

本文共 4323 字,大约阅读时间需要 14 分钟。

本博文主要讨论函数模板及其简单应用。

1)、作用:函数模板可以看做是一种代码产生器,往里面放入具体的类型,得到具体化的函数。

2)、编译(分为两步):

a):实例化之前,先检查模板本身语法是否正确;

b):根据 函数调用调用 ,先去实例化模板代码,产生具体的函数。

也就是说, 没有函数调用,就不会实例化模板代码,在目标文件obj中找不到模板的痕迹。

3):优缺点

模板的缺点是代码膨胀,编译速度慢,而优点是运行速度快。

一、函数模板:

1)、简单操作,代码实现如下:

1 #include 
2 #include
3 #include
4 using namespace std; 5 6 template
7 //修改办法2: 8 //T max(const T &a, const T &b) 9 const T &max(const T &a, const T &b)10 {11 return a > b ? a: b;12 }13 14 int main(int argc, const char *argv[])15 {16 cout << ::max(7, 42) << endl; //ok17 18 cout << ::max(5.5, 7.8) << endl; //ok19 20 string s1 = "hello"; 21 string s2 = "world";22 cout <<::max(s1, s2)<< endl; //ok23 24 //cout << ::max("hello", "worldd");//error char[6],char[7] 25 //虽然都是字符数组,但是长度也是参数的一部分,故两者不是同一类型26 27 //cout << ::max(3, 4.5) << endl;//error28 //会发生编译错误,因为编译器推断第一个类型为int,第二个为double,没有一个模板符合这个要求,这样就会发生强制转换而产生一个局部的中间变量。这个变量的引用作为return的返回值;即此时我们引用了一个局部变量,这时会产生错误. 29 //修改办法1:30 cout <<::max
(3, 6.5) << endl;31 cout << ::max(3, static_cast
(6.5)) << endl;32 33 return 0;34 }

2)、一个非模板函数可以和一个同名的函数模板同时存在;两者可以因为参数不同而构成重载;

模板函数重载时,现则函数版本的一些特点:

a):条件相同时,选择非模板函数;例如 ::max(7,42);

b):在强制类型转化,与可行的实例化模板之间,优先选择实例化模板;例如::max(7.0,43.5),::max(‘a’,‘b’);

c):若实例化版本不可行,则尝试普通函数的转化,例如::max(‘a’。42.7)

d)参数是指针时,优先选择可实例化模板的引用版本,若不存在,则优先选择指针版本;

e):总之,尽可能采用最匹配、开销最小的版本。

示例代码及注释如下:

1 #include 
2 #include
3 #include
4 using namespace std; 5 6 //调用策略--->精准调用 7 const int &max(const int &a, const int &b) 8 { 9 cout << "num.1"<< endl;10 return a> b? a: b;11 }12 13 template
14 const T *max(const T *a, const T *b)15 {16 cout <<"num.4" <
*b ? a:b ;18 }19 20 template
21 const T &max(const T &a,const T &b)22 {23 cout << "num.2" << endl;24 return a> b? a: b;25 }26 27 template
28 const T &max(const T &a, const T &b, const T &c)29 {30 cout << "num.3"<< endl;31 return ::max(::max(a, b), c);32 }33 34 int main(int argc, const char *argv[])35 {36 cout <<::max(7, 42, 68) << endl; //3 1 137 cout <<::max(7.0, 43.6) << endl; //238 cout <<::max('a','b') << endl;//2 char39 cout <<::max(7, 42) << endl;//240 cout <<::max<>(7,42) << endl; //2 特定模板41 cout << ::max
(7,42)<< endl;//242 cout <<::max('a', 43.7)<

3)、值传递与引用传递的区别:

a):值传递与引用传递对于形参而言,本质区别在于是否产生了局部变量

b):对于返回值而言,其区别在于, 返回时 是否产生了 临时变量

c): 对于非引用类型 的参数, 在实参演绎的过程中,会出现 从数组衰退成指针decay),从而丢失长度信息;而引用类型 则不会引发 衰退 decay

在模板函数重载中, 不要混合使用值传递和引用传递,而且要尽可能使用引用。

示例代码及注释如下:

1 #include 
2 #include
3 #include
4 #include
5 using namespace std; 6 7 //传引用 8 template
9 const T &max(const T &a, const T &b)10 {11 cout <<"num.1" << endl;12 return a> b? a: b;13 }14 15 //传值16 //修改1-->改为传引用17 //const char *&max(const char *&a, const char *&b)18 const char *max(const char *a, const char *b)19 {20 cout <<"num.2" << endl;21 return ::strcmp(a, b)> 0? a: b;22 }23 24 //传引用25 //修改2-->改为传值26 //const T max(const T &a, const T &b, const T &c)27 template
28 const T &max(const T &a, const T &b, const T &c)29 {30 cout <<"num.3" << endl;31 return ::max(::max(a, b), c);//return 临时变量32 //这里将临时变量的引用返回出去,可能导致错误33 //const char*tmp=::max(::max(s1,s2),s3)34 }35 36 int main(int argc, const char *argv[])37 {38 cout <<::max(7, 42, 68) << endl;39 40 const char *s1 = "beij";41 const char *s2 = "shangh";42 const char *s3 = "shenzh";43 44 cout <<::max(s1, s2, s3) << endl;45 46 return 0;47 }

decay衰退的简单示例:

1 #include 
2 #include
3 #include
4 using namespace std; 5 6 template
7 T max(T a, T b) //值传递-->退化成指针,返回得到是两个指针地址的较大者 8 { 9 return a > b ? a : b;10 }11 12 template
13 const T &max(const T &a, const T &b) //传引用14 {15 return a > b ? a : b;16 }17 18 int main(int argc, const char *argv[])19 {20 string s = "hello";21 22 ::max("hello", "world");23 ::max("apple", "orange");//error24 ::max("apple", s);25 26 return 0;27 }

 

转载于:https://www.cnblogs.com/xfxu/p/4001250.html

你可能感兴趣的文章
如何在手机网站上添加百度地图(带搜索功能)
查看>>
js正则表达式应用
查看>>
web基础,用html元素制作web页面
查看>>
Ubuntu 16.04安装GIMP替代PS
查看>>
使用SmartQQ实现的智能回复(Web QQ协议)
查看>>
redis下的字符串处理
查看>>
Servlet中Cookie的用法
查看>>
开源,选择Google Code还是Sourceforge
查看>>
传感器之超声波测距HC-SR04
查看>>
浅谈Java中的hashCode方法
查看>>
自己编写类似于枚举的类型(多例模式)
查看>>
Asp: Server.mapPath() 注意事项
查看>>
关于减少BUG的思考
查看>>
Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name) 中文显示乱码
查看>>
第二章随笔
查看>>
string.Format出现异常"输入的字符串格式有误"的解决方法
查看>>
SSL 1010——方格取数
查看>>
DB2数据库管理手册word版
查看>>
JDBC基础
查看>>
关于同余与模运算的总结
查看>>