首页 > 代码库 > C++学习之路: 函数模板
C++学习之路: 函数模板
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 using namespace std; 5 6 template <typename T> 7 T max(T a, T b) 8 { 9 return a > b ? a : b;10 }11 12 13 14 int main(int argc, const char *argv[])15 {16 int i = 42;17 cout << ::max(7, i) << endl;18 19 double f1 = 3.4;20 double f2 = -6.7;21 cout << ::max(f1, f2) << endl;22 23 string s1 = "hello";24 string s2 = "world";25 cout << ::max(s1, s2) << endl;26 27 28 return 0;29 }30 //次模板函数,是值拷贝型, 输入和返回值都是值拷贝,开销巨大, 如果我们 输入和返回值都是类类型的话, 对资源的消耗是巨大的。31 所以一般用下面这种模板
#include <iostream>#include <string>#include <vector>using namespace std;template <typename T>const T &max(const T &a,const T &b){ return a > b ? a : b;}int main(int argc, const char *argv[]){ int i = 42; cout << ::max(7, i) << endl; double f1 = 3.4; double f2 = -6.7; cout << ::max(f1, f2) << endl; string s1 = "hello"; string s2 = "world"; cout << ::max(s1, s2) << endl; return 0;}
上面这种模板,会节约很多。
下面介绍一种有坑的情况
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 using namespace std; 5 6 template <typename T> 7 const T &max(const T &a, const T &b) 8 { 9 return a > b ? a : b;10 }11 12 13 14 int main(int argc, const char *argv[])15 {16 //编译错误17 cout << ::max(4, 4.7) << endl;18 return 0;19 }
我们输入为 4-int 4.7-double , 编译器无法找到一个模板去匹配, 编译错误。
因为我们模板是两个参数都是T类型的, 而不是一个是T1,另一个是T2;
好吧,我们尝试一下两个参数类型是不同的模板
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 using namespace std; 5 6 template <typename T1, typename T2> 7 const T1 &max(const T1 &a, const T2 &b) 8 { 9 return a > b ? a : b;10 }11 12 13 14 int main(int argc, const char *argv[])15 {16 cout << ::max(3, 4.5) << endl; 17 // int double18 // const int &max(const int &, const double &);19 // 因为T1与T2类型不同,所以进行强制类型转换20 // 产生了一个中间临时变量21 // 所以最后的返回值,引用了一个临时变量22 23 return 0;24 }
上面是一个错误了例子, 编译不会通过, 错误十分隐晦, 我们看到 参数1是 T1, 参数2 是T2,
我们输入时 参数a是3 --int 参数b是4.5--double,那么我们告诉编译器去生成一个int &max(const int &, const double &)的函数,
返回值和 参数一都是T1==int, 显然 4.5 是比3大的, 所以返回的是4.5,但是我们要求返回值是int型, 显然也不匹配, 所以编译器会进行,强制转换 生成一个tmp = (int)4.5;
return tmp的引用。 tmp是临时变量, 该函数调用结束后栈空间被释放, 返回临时变量的引用是没有意义的。
所以导致编译错误
下面看一下模板的重载
例子代码:
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 5 using namespace std; 6 7 8 9 const int &max(const int &a, const int &b)10 {11 return a > b ? a : b ;12 }13 template <typename T>14 15 const T &max(const T &a, const T &b)16 {17 return a > b ? a: b ;18 }19 20 template <typename T>21 const T &max(const T &a, const T &b, const T &c)22 {23 return ::max(::max(a, b), c) ;24 }25 26 27 28 29 int main(int argc, const char *argv[])30 {31 ::max(7, 42, 68) ; //调用第三个32 ::max(7.0, 43.5) ; //调用第二个33 ::max(‘a‘, ‘b‘) ; //调用第二个34 ::max(7, 42) ; //调用第一个,其实第二个也可以,但是取最匹配的35 ::max<>(7, 42) ; //指定从模板2 进行匹配, 根据模板生成一个 int &max(const int &, const int &)36 cout << ::max<double>(7,42) <<endl; // 调用2 进行强制转换。37 cout << ::max(‘a‘, 42.7) << endl; //调用1, 进行强制转换38 return 0;39 }
总之不需要死记调用的规则, 掌握一个原则, 编译器总是选择调用最合适的那个函数。
C++学习之路: 函数模板
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。