《C++ Template. The Complete Guide》笔记之二 Function Templates

大约是受宏(预处理)的压迫太深,所以有了模板以后的第一件事情便是定义模板函数来取代那些MAX和MIN。作者也乐得如此,下面我就马上来看一个最简单的模板函数max的实现:

如果费力的逐个解释一下的话,那大概是这样:template表明了这是一个模板函数,<>指定了模板参数区域,typename表明了后面的参数是一个类型名,而T则表明了一种广泛意义上的类型,它可以用来指定所有的类型(int, float, std::string)。所有的这些构成了一个最基本的模板函数,需要说明的一点是由于历史的原因,这里的typename可以用class来取代。(我们确实看到很多都是用class来描述的)。当然也有人问了,那struct是不是也可以,答案当然是不可以!

了解了这个函数的定义,第二步要做的就是探索如何调用它。这里有几个例子:

第一个和第二个调用没有任何问题,就像普通的函数调用,当然他们的调用是可以成功的。但是到第三个调用的时候,问题出现了,编译器报了一个错误'const T &max(const T &,const T &)' : template parameter 'T' is ambiguous。可以看到这里的参数类型出了问题,两个参数的类型不一致。一个是int一个double,所以编译器不知道怎么指定T,注意这里编译器需要的是一个确切的类型,所以他是不会主动给你做任何类型转化的。那怕从int32到int16都不会。所以在这里你需要显示地告诉编译器你要怎么做,这就是第四个调用max<double>(1, 2.5);或者你也可以强制转化一下参数1,让他转化成double然后调用,比如说max(static_cast<double>1, 2.5)

更进一步,我们来看看编译器是如何帮助我们实现这些调用的。简单的说,编译器采用的办法就是存在什么类型的调用,我就给你产生一堆什么类型对应的max代码。比如说max(1,2);调用来的时候,我就给你生成一段这样的代码:

就是用int来替代了原来的T产生了具体类型的代码,这样原来程序员需要为不同类型版本写函数的工作就交给了编译器来做。编译器为不同类型生成对应函数代码的过程被称之为实例化(Instantiation,很巧和OO里面的实例化是同一个词。当然意义是决然不同的)。接下来我们可以看看一个复杂一点的例子:

这是一个完整的运行在VS2005下的例子。这里的不同就是模板函数有了不同的重载的版本,这里在实例化之前,就需要为不同的类型找到一个最合适的函数调用,比如说调用max(a,b);的时候,a,b都是int,编译器发现第一个max函数,也就是以value作为参数的版本最为匹配,所以会就此实例化出一个第一个函数的int版本,注意这里这种匹配的流程被称之为演绎(Deduction)。而演绎的基本的原则就是首先匹配并存的非模板函数,如果不成功就寻找最接近的模板函数。比如max(s1,s2);的时候,匹配到的就是const char*的那个版本的max函数,而max(a1, a2);的时候就是第二个max函数,也就是以指针作为类型参数的版本。

到目前为止还是一派鸟语花香,聪明的编译器做到我们希望的一切,max的表现和预想的出奇的一致。当然不得不提的一点就是平静之下的惊涛暗涌。且看下面的例子:

可以看到如果这些模板参数类型不匹配的话,带来的问题有多大,可以看到max(7,42,68);的时候没有问题,3个参数的max函数匹配到第一个max函数,这里没有问题,大家都是传引用的语义。但是到max(s1,s2,s3);的时候,那个max(max(a,b),c);匹配到了const char*的max版本,这样,max的返回值就从引用改成了栈上值。尽管这里的comment写了ERROR,但实际上VS2005中只会报一个returning address of local variable or temporary的warning!那些以error为判断条件的筒子们应该注意了,其实这样的warning也会是致命的。所以聪明的编译器带给我们的并不是总是放心的。

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ Template》第二版,2017年9月16日出版 Templates are among the most powerful features of C++, but they remain misunderstood and underutilized, even as the C++ language and development community have advanced. In C++ Templates, Second Editi on, three pioneering C++ experts show why, when, and how to use modern templates to build software that’s cleaner, faster, more efficient, and easier to maintain. Now extensively updated for the C++11, C++14, and C++17 standards, this new edition presents state-of-the-art techniques for a wider spectrum of applications. The authors provide authoritative explanations of all new language features that either improve templates or interact with them, including variadic templates, generic lambdas, class template argument deduction, compile-time if, forwarding references, and user-defined literals. They also deeply delve into fundamental language concepts (like value categories) and fully cover all standard type traits. The book starts with an insightful tutorial on basic concepts and relevant language features. The remainder of the book serves as a comprehensive reference, focusing first on language details and then on coding techniques, advanced applications, and sophisticated idioms. Throughout, examples clearly illustrate abstract concepts and demonstrate best practices for exploiting all that C++ templates can do. Understand exactly how templates behave, and avoid common pitfalls Use templates to write more efficient, flexible, and maintainable software Master today’s most effective idioms and techniques Reuse source code without compromising performance or safety Benefit from utilities for generic programming in the C++ Standard Library Preview the upcoming concepts feature The companion website, tmplbook.com, contains sample code and additional updates.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值