1.函数模版类型形参转换
一般在调用模版函数的时候,不同的实参数据类型会使模版产生不同数据类型的函数实例,而对实参不进行类型转换。
但是编译器会进行下面两中转换
上面的话怎么理解呢?举个例子:
1、const转换:接受const引用或const指针的函数分别用非const对象的引用或指针来调用,无需产生新的实例化。如果函数接受非引用类型,形参类型和实参都忽略const,即,无论传递const或非const对象给接受非引用类型的函数,都使用相同的实例化。
2、数组或函数到指针的转换:如果模板形参不是引用类型,则对数组或函数类型的实参应用常规指针转换。数组实参将当作指向其第一个元素的指针,函数实参当作指向函数类型的指针。
2.模版特化:实例化一个特殊的版本用来专门处理特殊的参数类型。
模版特化分为全特化和偏特化。
1.函数模版的特化,只能是全特化
首先看下面的函数模版
template<typename T>
int compare(T c1,T c2)
{
if (c1 > c2)return 1;
if (c1 < c2)return 0;
else return -1;
}
对于这个函数模版,当两个形参为char指针的时候,比较的是指针的大小,而不是指针指向内容的大小,此处就需要为该函数定义一个特化版本,就是函数的特化,代码如下:
template<>
int compare<const char *>(const char *const c1, const char *const c2)
{
return (strcmp(c1, c2));
}
1. template <> //空模板形参表2: compare<const char *> //模板名字后指定特化时的模板形参即const char *类型,就是说在以实参类型 const char * 调用函数时,将产生该模板的特化版本,而不是泛型版本,也可以为其他指针类型定义特化版本如int *.
c: (const char * const &v1, const char * const &v2)//可以理解为: const char * const &v1, 去掉const修饰符,实际类型是:char *&v1,也就是v1是一个引用,一个指向char型指针的引用,即指针的引用,加上const修饰符,v1就是一个指向const char 型指针的 const引用,对v1的操作就是对指针本身的操作,操作方式与指针一致,比如*v1,是正确的;//注意这里的const char *, 由于形参是一个指向指针的const引用,所以调用特化版本时的实参指针类型(并非存储的数据的类型)可以为const也可以为非const,但是由于这里形参指针指向的数据类型为const char *(强调存储的数据是const),所以实参指针所指向的数据类型也必须为const,否则类型不匹配;
2.类模版的特化,分为全特化和偏特化
1.全特化
什么叫特化。特化其实就是特殊化的意思,在模板类里,所有的类型都是模板(template<class T>),而一旦我们将所有的模板类型T都明确化,并且写了一个类名与主模板类名相同的类,那么这个类就叫做全特化类。代码如下
//主模版
template<class T1,class T2>
class stu
{
public:
stu(T1 a, T2 b)
{
cout << "类主模版" << endl;
}
};
//全特化
template<>
class stu<int, double>
{
public:
stu(int a, double b)
{
cout << "全特化" << endl;
}
};
int main()
{
stu<int, double> a(1, 2);//调用全特化的类
return 0;
}
注意:
上面代码就是经过全特化的类A,可以看到主版本模板类中的T1和T2已经全部明确化为int和double。接着在main里用“A<int, double> a;”实例化对象时,程序会去调用这个全特化的类。一个类被称为全特化类的条件:1.必须有一个主模板类 2.模板类型被全部明确化。
1.偏特化
上面对主版本模板类和全特化类进行了定义,那么偏特化就是介于二者之间的模板类,它的类名与主版本模板类相同,但是它的模板类型中,有被明确化的部分和没有被明确化的部分。代码如下
//主模版
template<class T1,class T2>
class stu
{
public:
stu(T1 a, T2 b)
{
cout << "类主模版" << endl;
}
};
//偏特化
template<class T>
class stu<int, T>
{
public:
stu(int a, double b)
{
cout << "全特化" << endl;
}
};
int main()
{
stu<int, double> a(1, 2);//调用全特化的类
return 0;
}
上面代码就是一个偏特化的模板类,可以看到主版本模板类中的T1和T2中的T1被明确化为int。接着在main里用“A<int, char> a;”实例化对象时,程序会去调用这个偏特化的。一个类被称为偏特化类的条件:1.必须有一个主模板类 2.模板类型被部分明确化。
3.模版的模版参数
用一下代码简单的举例:
1.问题的引用,这段代码可以看懂吧,看不懂私我,哈哈!
2.
第二幅图就是模版的模版参数