模板——泛型和STL的基础

        所谓泛型,从字面上可以猜想,就是泛化的类型(型别、type)。那么是在什么时候,类型被泛化了呢?我们知道,在编写一个函数的时候,通常都会知道参数(parameter)是什么类型的,很多时候这是理所当然的事情,连类型都不知道,怎么对传入参数进行操作呢?面对这样类似的疑问,C++总会展露出她迷人的笑容,让人消魂。这次,她用温柔的声线告诉我:“我可是能实现可以接受任何适当类型参数的函数哦。
        不会吧,我可没有用Java写过这样的函数哦。嘿嘿,偶还没有勇气去养“老虎”,所以只能这样大惊小怪了。
        其实,我们是可以理解语言支持泛型的,如果为了针对不同的类型去实现相同的行为就要去将代码重复再重复,就真的太笨了,代码重复也正是代码坏味道的一种。在Java中,如ArrayList,Vector都是使用对象数组(Object[])来储存数据的,也就是说这些Collection是基于基础类型(base type)而实现,这样才能使得这个Collection具有通用性,即使如此,ArrayList和Vector也不能存储基本类型(primitive type),因为对象数组的元素根本就不能是int、double这样的基本类型,这样类型是不匹配的。除了这个缺点之外,由于实现这些Collection是基于基础类型的,因此编译器无法进行类型检查,同时也就没有办法进行Collection元素之间关系的处理了。举个简单例子,即使一个ArrayList只是装了Integer类型的数据,编译器都没有办法知道,同时也没有办法直接对这个ArrayList进行操作,从中找出最大值。这就是缺少范型支持的一个大缺陷了。泛型如此重要,而模板函数正是实现泛型函数的基础。

        重温C++的旧梦,我是从标准库开始的,在标准库中,处处都能看到template关键字的身影。Almost all parts of the library are written as templates. Without template support, you can't use the standard library. [1]
        看来还是从最根本的开始了——Template(模板)。在这里,我主要将注意力集中在模板函数上。以下是一个最简单的模板函数:

None.giftemplate <class T>  
None.gifinline T 
const& max (T const& a, T const&  b) 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif    
return a < b ? b : a; 
ExpandedBlockEnd.gif}
  
None.gif

        我们在调用模板函数的时候跟调用一般的函数是没有什么区别的:

None.gif#include <iostream>
None.gif#include 
<string>
None.gif#include 
<vector>
None.gif#include 
"max.hpp"
None.gif
ExpandedBlockStart.gifContractedBlock.gif
int main() dot.gif {
InBlock.gif    
int i = 42
InBlock.gif    std::cout 
<< "max(7,i): " << max(7,i) << std::endl; 
InBlock.gif
InBlock.gif    
double f1 = 3.4
InBlock.gif    
double f2 = -6.7
InBlock.gif    std::cout 
<< "max(f1,f2): " << max(f1,f2) << std::endl; 
InBlock.gif
InBlock.gif    std::
string s1 = "mathematics"
InBlock.gif    std::
string s2 = "math"
InBlock.gif    std::cout 
<< "max(s1,s2): " << ::max(s1,s2) << std::endl; 
ExpandedBlockEnd.gif}

        模板函数之所以能够接受任何类型的参数,其实是在编译的过程中,根据模板使用的情况编译成相应的一般的函数去处理这些不同的参数。譬如例子中有三次调用,就会将模板函数编译成三种版本以处理这三种不同类型的参数了。对于第一个调用max( 7, i ),就是使用了将模板函数中的T替换成int的版本,这也说明了如果这样调用是会无法通过编译的:max ( 7,  3.4 )。
        除此之外,所谓能够接受任何类型的参数,其实也是有限制的。譬如说,max函数中的"<"操作父约束了参数a和b的类型,至少这两个参数能够支持这样的操作才是合法的。

        [1] C++ Standard Library, The: A Tutorial and Reference

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值