在C++开发中,模板分为函数模板:函数模板和类模板。
模板参数可以是一个模板类型参数,它代表了一个类型;也可以是一个模板非类型参数,它代表了一个常量表达式,即,它必须能在编译时被计算出结果。例如:
一,函数模板
在函数模板实参推演中,函数模板类型参数和类型实参不必完全匹配,下列类型转换可以被应用到函数实参上以便将其转换成相应的函数参数的类型
1.左值转换:数组到指针或函数到指针的转换
2,限定修饰转换:把非const/volatile转换为const/volatile
3,从派生类到基类的转换
在一些推演中,无法确定模板实参的类型,这时我们需要改变模板实参推演机制,并使用显示指定 模板实参。例如:
有时我们只需列出不能被隐式推演的模板实参,如果确省实参一样,这时我们只能省略尾部的实参。
有这样一个模板函数
但type是const char*,这种比较方式是不行的,所以函数特化,如下所示:
函数模板不支持偏特化,类的成员函数依然不支持。
二,类模板
在模板实参的类型和非类型模板参数的类型之间允许一些转换,例如:
1,左值转换,包括左值到右值的转换,从数组到指针的转换,从函数到指针的转换。
2,限定修饰转换,例如:从int*到const int*的转换
3,提升,例如:从short到int的提升
4,整值转换,例如:从int到unsigned int的转换
模板特化,相信很多人都很熟悉 ,但是说到模板特化的几种类型,相信了解的人就不是很多。我这里归纳了针对一个模板参数的类模板特化的几种类型, 一是特化为绝对类型; 二是特化为引用,指针类型;三是特化为另外一个类模板。实际上第二种和第三种是偏特化或是部分特化。 这里用一个简单的例子来 说明这三种情况:
这是一个用于比较的类模板,里面可以有多种用于比较的函数, 以IsEqual为例。
一、特化为绝对类型
也就是说直接为某个特定类型做特化,这是我们最常见的一种特化方式, 如特化为float, double等
二、特化为引用,指针类型
这种特化我最初是在stl源码的的iterator_traits特化中发现的, 如下:
当然,除了T*, 我们也可以将T特化为 const T*, T&, const T&等,以下还是以T*为例:
这种特化其实是就不是一种绝对的特化, 它只是对类型做了某些限定,但仍然保留了其一定的模板性,这种特化给我们提供了极大的方便, 如这里, 我们就不需要对int*, float*, double*等等类型分别做特化了。
三、特化为另外一个类模板
这其实是第二种方式的扩展,其实也是对类型做了某种限定,而不是绝对化为某个具体类型,如下:
这就把IsEqual的参数限定为一种vector类型, 但具体是vector<int>还是vector<float>, 我们可以不关心, 因为对于这两种类型,我们的处理方式是一样的,我们可以把这种方式称为“半特化”。
当然, 我们可以将其“半特化”为任何我们自定义的模板类类型:
这就是三种类型的模板特化, 我们可以这么使用这个Compare类:
当一个模板的参数不止一个时,也会使用偏特化
本文转自:http://blog.csdn.net/flyingtimeice/archive/2009/02/19/3910846.aspx