博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++函数模板
阅读量:6329 次
发布时间:2019-06-22

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

函数模板提供了一种函数行为,该函数行为可以用多种不同的类型进行调用,也就是说,函数模板代表一个函数家族,这些函数的元素是未定的,在使用的时候被参数化。

本文地址:,转载请注明源地址。

下面举一个简单的例子:

定义模板:

template
inline T const& max(T const& a, T const& b){ return a < b ? b : a;}

这个模板定义指定了一个“返回两个值中最大者”的函数家族,这两个值通过函数参数a , b传递给函数模板的,而参数的类型还没有确定,用模板参数T来代替。

其中,typename可以用class来代替,但是建议使用typename

完整代码如下:

#include
#include
using namespace std;template
inline T const& max(T const& a, T const& b){ return a < b ? b : a;}int main(){ int i = 42; cout<<"max(7, i): "<<::max(7, i)<

实参的选择:

模板参数可以根据我们传递的实参来决定,如果我们传递了两个int给参数类型T const&,那么C++编译器得出结论:每个T都必须正确的匹配,如果此时传递的实参为:max(4, 4.2),则出现编译错误

有3种方法来处理上面的错误:

1、对实参进行强制类型转换,使它们可以互相匹配:

max(static_cast<double>(4), 4.2);

2、显示指定(或限定)T的类型:

max<double>(4, 4.2)

3、指定两个参数可以具有不同的类型

 模板参数

函数模板有2种类型的参数:

1、模板参数:位于函数模板名称的前面,在一对尖括号内部进行声明:

template<typename T>

2、用参数:位于函数模板名称之后,在一对圆括号内部进行声明:

...max(T const& a, T const& b)

可以声明任意数量的模板参数,在函数模板的内部,不能指定缺省的参数。

template
inline T1 max(T1 const& a, T2 const& b){ return a < b ? b : a;}...max(4, 4.2);

可以引入第三个模板实参类型,来定义函数模板的返回类型:

template
inline RT max(T1 const& a, T2 const& b);...max
(4, 4.2);

行得通,但是很麻烦

还有一种方法是只显示的指定第一个实参,而让演绎过程推导出其余的实参。

template
inline RT max(T1 const& a, T2 const& b);...max
(1, 4.2); //ok, 返回类型是double

 重载函数模板

和普通函数一样,函数模板也可以被重载,示例代码如下:

#include
#include
using namespace std;inline int const& max(int const& a, int const& b){ return a < b ? b : a;}template
inline T const& max(T const& a, T const& b){ return a < b ? b : a;}template
inline T const& max(T const& a, T const& b, T const& c){ return ::max(::max(a, b), c);}int main(){ cout<<::max(7, 12, 67)<
(通过实参演绎) cout<<::max('a', 'y')<
(通过实参演绎) cout<<::max(7, 42)<
(7, 23)<
(通过实参演绎) cout<<::max
(4, 45)<
(没有实参演绎) cout<<::max('a', 23.4)<

  下面的更有用的例子将会为指针和普通的C字符串重载这个求最大值的模板:

#include
#include
using namespace std;//求两个任意类型值的最大者template
inline T const& max(T const& a, T const& b){ return a < b ? b : a;}//求两个指针所指向值的最大者template
inline T* const& max(T* const& a, T* const& b){ return a < b ? b : a;}//求两个C字符串的最大者inline char const* const& max(char const* const& a, char const* const& b){ return *a < *b ? b : a;}int main(){ int a, b; a = 7; b = 42; ::max(a, b); //max()求两个int值的最大值 string s = "hey"; string t = "you"; cout<<::max(s, t)<

以上在所有实现重载里面,都是通过引用来传递每个实例的,但是一般而言,在重载函数模板的时候,最好只是改变那些需要改变的内容,应该把改变限制在以下两个方面:

改变参数的数目或显式地指定模板参数

 对于以上的重载,如果改为基于C-string的max()函数,通过传值来传递参数,就不能实现3个参数的max()版本:

#include
#include
using namespace std;//求两个任意类型值的最大者(通过传引用进行调用)template
inline T const& max(T const& a, T const& b){ return a < b ? b : a;}//求两个C字符串的最大者(通过传值进行调用)inline char const* max(char const* a, char const* b){ return strcmp(a, b) < 0 ? b : a;}//求3个任意类型值的最大者(通过传引用进行调用)template
inline T const& max(T const& a, T const& b, T const& c){ return max(max(a, b), c);}int main(){ cout<<::max(7, 42, 68)<

错误在于:如果对3个C-string调用max,则语句return max(max(a, b), c);将产生错误

原因是对于C-string而言,max(a, b)产生了一个新的临时局部值,该值有可能被外面的max函数以传引用的方式返回,将导致传回无效的引用。

 

 

你可能感兴趣的文章
调试网页PAIP HTML的调试与分析工具
查看>>
路径工程OpenCV依赖文件路径自动添加方法
查看>>
玩转SSRS第七篇---报表订阅
查看>>
WinCE API
查看>>
POJ 3280 Cheapest Palindrome(DP 回文变形)
查看>>
oracle修改内存使用和性能调节,SGA
查看>>
SQL语言基础
查看>>
对事件处理的错误使用
查看>>
最大熵模型(二)朗格朗日函数
查看>>
深入了解setInterval方法
查看>>
html img Src base64 图片显示
查看>>
[Spring学习笔记 7 ] Spring中的数据库支持 RowMapper,JdbcDaoSupport 和 事务处理Transaction...
查看>>
FFMPEG中关于ts流的时长估计的实现(转)
查看>>
Java第三次作业
查看>>
【HDOJ 3652】B-number
查看>>
android代码混淆笔记
查看>>
Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) C. String Reconstruction 并查集
查看>>
BMP文件的读取与显示
查看>>
Flash文字效果
查看>>
各种排序算法总结篇(高速/堆/希尔/归并)
查看>>