C++中分为函数模板和类模板,它们之间的相同点是都含有模板型参表,不同点在模板实例化的时候函数模板可以不用显示的声明模板类项,编译器会自动帮我们匹配,而类模板则需要显示定义出来,例如:
template <class Type> compare(Type& , Type&); compare(a,b);
template <class Type> class Queue { ... } class<int> test;
1.函数模板中编译器帮我们做了实例化的事情,那么它遵循的是什么规则呢?
首先,编译器首先考虑产生新的实例,而不是转化实参以匹配已有的实例化,以上 面compare为例:
int a1= 3,a2 = 4;
long b1 = 3,b2 = 4;
compare(a1,a2);
compare(b1,b2);
编译器首先实例化一个compare(int,int),当遇到b1,b2时,不会考虑对b1,b2进行类 项转化,而是又实例化了一个 compare(long,long).
但是也有例外,编译器会在以下两中情况下执行转化而不去产生新的类项:
1>. const转换,既你可以把非const类项对象的引用或指针传到接受const类项的函数中而不产生实例化,或者传递对象给接受非引用类项的函数时也不会产生实例化。
2>.数组或函数到指针的转化;
2.函数模板的显式实参
有时候我们不确定模板实参的类项,如:
template<class T,class U> ??? sum(T,U) ,我们想要返回T,U类项中范围最大的那个,该怎么办呢?
一种是指定显示模板参数,如sum(static_cast<int> short, int),既把小范围的给强制转换成范围大的类项。
还有一种是在返回类项中再使用类项行参,如:
template<class T,class U, class K> T sum(U,K);
long val = sum<long>(int ,long);
3.函数模板特化
有时候模板函数并不能帮我们解决所有问题,比如compare函数,当我想比较指向字符串的指针时,很显然我想比较的是字符串的字典序,而不是两个指针的大小,这个时候就需要我们用模板特化的技术了。
模板特化的格式是这样的:
template<> int compare<const char*> (const char* const , const char* const )
我的理解就是把模板参数列表从template移到了后面,同时模板特化是不支持类项转化的,传入的参数类项必须完全匹配,如果不匹配的化,它会去普通模板中查看是否能够实例化。