模板:类模板和函数模板。
一、模板实参推断:
定义:从函数实参确定模板实参的类型和值的过程叫做模板实参推断。
1、多个类型形参的实参必须完全匹配。
template <typename T>
int compare (const T& v1, const T& v2)
{
if(v1 < v2) return 1;
else return 0;
}
int main()
{
short s;
compare(s,1024);//error
}
这里是错误的,因为调用comare时的实参类型不相同。第一个实参推断出的模板类型是short,第二个是int,类型不匹配,所以模板实参推断失败。
如果想要允许实参的常规转换,函数必须用两个类型形参来定义:
template <typename A, typename B>
int compare(const A& vi, const B& v2)。。。
2、类型形参的实参的受限转换。
一般不会转换实参以匹配已有的实例化,会产生新的实例。
编译器只会接受两种转换:
const转换:接受const引用或const指针的函数,可以分别用非const对象的引用和指针来调用,无须产生新的实例化。如果函数接受非引用类型,形 参类型和实参都忽略const。即,无论传递const或非const对象给接受非引用类型的函数,都使用相同的实例化。
数组或函数到指针的转换:如果模板形参不是引用类型,则对数组或函数类型的实参应用常规指针转换。数组实参将当做指向其第一个元素的指针,
函数实参当做指向函数类型的指针。
3、应用于非模板实参的常规转换
用普通类型定义的形参可以使用常规转换。
4、模板实参推断与函数指针
可以使用函数模板对函数指针进行初始化和复制,这样做时,编译器使用指针的类型实例化具有适当模板形参的模板版本。
如下:
template <typename T>
int compare(const T& , const T&);
type int (*pf) (const int& a, const int& b) fun;
fun t = compare.
t的类型是函数指针,指向“接受两个const int&类型形参并返回int值得函数”,形参的类型决定了T的模板实参的类型。指针t的引用是将T绑定到int的实
例化。
如果不能从函数指针类型确定模板实参,就会报错。
void func(int (*) (const string&,const string&);
void func(int (*) (const int&,const int&);
func(compare)//报错。
问题在于,通过查看func的形参类型不可能确定模板实参的唯一类型,对func的调用可以实例化下列函数中的任意一个,
compare(const string&,const string&);
compare(const int &,const int &);
因为不能为传给func的实参确定唯一的实例,所以出错。
二、函数模板的显式实参
1、在返回类型中使用类型形参
compare<string,string>(a,b);
2、显示实参与函数模板指针
可以使用显示模板实参消除二义性。
func(compare<int>);//ok.