《C++ Templates中文版》——2.3 模板参数-阿里云开发者社区

开发者社区> 异步社区> 正文

《C++ Templates中文版》——2.3 模板参数

简介:
+关注继续查看

本节书摘来自异步社区出版社《C++ Templates中文版》一书中的第2章,第2.3节,作者: 【美】David Vandevoorde , 【德】Nicolai M. Josuttis,更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.3 模板参数

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

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

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

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

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

你可以根据需要声明任意数量的模板参数。然而,在函数模板内部(这一点和类模板有区别),不能指定缺省的模板实参[4]。例如,你可以定义一个“两个调用参数的类型可以不同的”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);

然而,模板实参演绎并不适合返回类型[6],因为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()就是一个不错的主意(在接下来的几节里,当讨论其他模板话题的时候,我们将使用这种方法)。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Hibernate-ORM:07.Hibernate中的参数绑定
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------     本篇博客会讲解Hibernate中的参数绑定,就是相当于sql语句中的where后面的条件   一,讲解概述:   1.
890 0
js传递中文参数的url到asp(jscript)解释得到的中文参数为乱码的解决方法
  js传(编码为65001)递中文参数的url到asp(jscript,编码为65001)需编码中文参数 Server.UrlEncode(中文参数)
704 0
会员卡开卡表单模板配置(alipay.marketing.card.formtemplate.set)JAVA版本demo
官方接口文档:[url]https://docs.open.alipay.com/251/105668/[/url],我这里写的是开卡组件前两步的操作流程,仅供参考 1.调用接口前的准备工作(创建应用等)参考该文档:[url]https://docs.
740 0
Java模板模式(template)
java23中设计模式中的模板模式是我们经常在框架源码中能看到的设计模式,所以本文就给大家来介绍下模板模式
10 0
+关注
异步社区
异步社区(www.epubit.com)是人民邮电出版社旗下IT专业图书旗舰社区,也是国内领先的IT专业图书社区,致力于优质学习内容的出版和分享,实现了纸书电子书的同步上架,于2015年8月上线运营。公众号【异步图书】,每日赠送异步新书。
12049
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载