频 道 直 达 - 新闻 - 培训 - 软件 - 教程 - 前沿 - 组网 - 系统应用 - 安全 - 编程 - 存储 - 操作系统 - 数据库 - 服务器 - 专题 - 产品 - 案例库 - 读书 - 博客 - BBS
51CTO.COM_中国最大的网络技术网站
找资料:

2.3 模板参数

作者: 陈伟柱 出处:人民邮电出版社  2008-03-28 22:01    砖    好    评论   进入论坛
阅读提示:《C++ Templates》中文版是C++模板编程的完全指南,旨在通过基本概念、常用技巧和应用实例3方面的有用资料,为读者打下C++模板知识的坚实基础。本文介绍了实参的演绎。

2.3  模板参数

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

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

         template <typename T>       //T是模板参数

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

         …max (T const& a, T const& b)   //a和b都是调用参数

你可以根据需要声明任意数量的模板参数。然而,在函数模板内部(这一点和类模板有区别),不能指定缺省的模板实参 。例如,你可以定义一个“两个调用参数的类型可以不同的”max()模板:

template <typename T1, typename T2>
inline T1 max (T1 const& a, T2 const& b)
{
return  a < b ? b: a;
}

max(4,4.2)      //OK, 但第1个模板实参的类型定义了返回类型

这看起来是一种能够给max()模板传递两个不同类型调用参数的好方法,但在这个例子中,这种方法是有缺点的。主要问题是:必须声明返回类型。对于返回类型,如果你使用的是其中的一个参数类型,那么另一个参数的实参就可能要转型为返回类型,而不会在意调用者的意图。C++并没有提供一种“指定并且选择一个‘最强大类型’”的途径(然而,你可以使用一些tricky模板编程来提供这个特性,详见15.2.4小节)。于是,取决于调用实参的顺序,42和66.66的最大值可以是浮点数66.66,也可以是整数66。另一个缺点是:把第2个参数转型为返回类型的过程将会创建一个新的局部临时对象,这导致了你不能通过引用 来返回结果。因此,在我们的例子里,返回类型必须是T1,而不能是T1 const&。

因为调用参数的类型构造自模板参数,所以模板参数和调用参数通常是相关的。我们把这个概念称为:函数模板的实参演绎。它让你可以像调用普通函数那样调用函数模板。

然而,如前所述,针对某些特定的类型,你还可以显式地实例化该模板:

template <typename T>
inline T const& max (T const& a, T const& b);

max<double>(4,4.2)    //用double来实例化T

当模板参数和调用参数没有发生关联,或者不能由调用参数来决定模板参数的时候,你在调用时就必须显式指定模板实参。例如,你可以引入第3个模板实参类型,来定义函数模板的返回类型:

template <typename T1, typename T2, typename RT>
inline RT max (T1 const& a, T2 const& b);

然而,模板实参演绎并不适合返回类型 ,因为RT不会出现在函数调用参数的类型里面。因此,函数调用并不能演绎出RT。于是,你必须显式地指定模板实参列表。例如:

template <typename T1, typename T2, typename RT>
inline RT max (T1 const& a, T2 const& b);

max<int, double, double>(4,4.2)    //OK, 但是很麻烦

到目前为止,我们只是考察了显式指定所有函数模板实参的例子,和不显式指定函数任何模板实参的例子。另一种情况是只显式指定第一个实参,而让演绎过程推导出其余的实参。通常而言,你必须指定“最后一个不能被隐式演绎的模板实参之前的”所有实参类型。因此,在上面的例子里,如果你改变模板参数的声明顺序,那么调用者就只需要指定返回类型:

template <typename RT, typename T1, typename T2>
inline RT max (T1 const& a, T2 const& b);

max<double>(4,4.2)   //OK: 返回类型是double

在这个例子里,调用max<double>时显式地把RT指定为double,但其他两个参数T1和T2可以根据调用实参分别演绎为int和double。

可以看出,所有这些修改后的max()版本都不能得到很大的改进。由于在单(模板)参数版本里,如果传递进来的是两个不同类型的实参,你已经可以指定参数的类型(和返回类型)。因此,尽量保持简洁并且使用单参数版本的max()就是一个不错的主意(在接下来的几节里,当讨论其他模板话题的时候,我们将使用这种方法)。

关于演绎过程的更多内容请参照第11章。


回书目   上一节   下一节
专题
C++是垃圾语言?!
VC++基础开发专题
C++开发专栏
C++ Templates:中文版
C++沉思录
我也说两句

匿名发表

(如果看不清请点击图片进行更换)


中 国 最 大 的 网 络 技 术 网 站 ·
技 术 成 就 梦 想
订阅技术快讯
电子杂志下载
名称:SQL Server数据库管理精品黄皮书
简介:书中文章经过精挑细选,便于用户能根据自己的实际工作和学习,快速在本书寻找到相关资料。内容涵盖了SQL Server的安装与升级、语句查询、数据备份和恢复、自动化任务、数据同步、数据字典、安全和预防、性能和优化、集群等各方面应用信息,以及DBA管理人员在数据库管理工作中
名称:2007路由技术大全
简介:《2007路由技术大全》由51CTO.com网站特别策划制作,该书包括路由器技术、路由器产品、路由器配置、安全设置、路由器故障处理、路由器密码恢复,以及广大网友在实践使用中的心得经验和技巧文章,内容注重实用性,适用于初学者入门,也适合多年从业者提高,是一本实践和理论完
名称:网络安全精品应用黄皮书
简介:《2007精品网络安全黄皮书》包括了9个大类24个小类, 800余篇文章,内容包含了熊猫烧香病毒、DDOS攻击、ARP病等热点问题的介绍及解决方案。从病毒查杀、防范、系统、数据等各方面的安全设置到黑客技术的了解、防范,涉及到了安全应用的全部领域, 由浅至深内容全面。
国际文档格式标准开战
国际文档格式标准开战
初探敏捷开发
初探敏捷开发
Linux——从菜鸟到高手
Linux——从菜鸟到高手
· Linux——从菜鸟到高手
· 体验Visual Studio 200..
· SOA 面向服务架构
· CISSP认证成长之路
· 隐私保护技术探讨
· WCF开发基础
· 珊瑚虫QQ作者侵权案开庭
· SQL Server 2008/2005..
· 华为员工自杀频频拷问..
· 计算机网络维护入门
· 开源虚拟化技术Xen
· 贝恩资本携手华为22亿..
· 如何优化IT 控制能耗
· VMware技术应用
· 打造安全服务器
· iSCSI应用与发展
清除流氓软件——51CTO特别专题
清除流氓软件——51CTO特别专..
ARP攻击防范与解决方案
ARP攻击防范与解决方案
iSCSI应用与发展
iSCSI应用与发展
· iSCSI应用与发展
· SQL Server 2008/2005..
· SOA 面向服务架构
· SQL Server 2008/2005..
· iSCSI应用与发展
· RAID——磁盘阵列基础
· 中间件应用技术专题
· 病毒查杀专题
· 国际文档格式标准开战
· Linux防火墙
· 打造安全服务器
· Sniffer安全技术从入门..
· SOA 面向服务架构
· ADSL应用面面俱到
· 入侵防护系统(IPS)初探
· TCP/IP协议专题
ARP攻击防范与解决方案
ARP攻击防范与解决方案
SQL Server 2008/2005全解
SQL Server 2008/2005全解
iSCSI应用与发展
iSCSI应用与发展
· iSCSI应用与发展
· 中间件应用技术专题
· SQL Server 2008/2005..
· SOA 面向服务架构
· iSCSI应用与发展
· RAID——磁盘阵列基础
· 身份认证技术
· 病毒查杀专题
· 清除流氓软件——51CTO..
· Sniffer安全技术从入门..
· SOA 面向服务架构
· 了解统一威胁管理(UTM)..
· ADSL应用面面俱到
· ADSL应用面面俱到
· 反垃圾邮件技术应用
· TCP/IP协议专题