模板本身是一个蓝本(blueprint),它并不是类或者函数。
编译器根据模板实参产生类型明确(typr-specific)的模板实例称为模板实例化。例如标准库vector,使用时 vector
myvec,产生一个元素类型为int的vector。编译器重写vector模板,用int替换相应的模板参数。如果再有代码 vector myvec2,编译器会再产生一个元素类型为float的vector实例。
模板在使用时才进行实例化,类模板在引用具体模板类时实例化,函数模板在调用时或用它对函数指针赋值时实例化。
实例化时,模板参数的实参必须与模板形参完全匹配,否则编译器报错。
template <typename T>
func(T para_1, T para_2){
//....
}
|
两个同类型的函数参数,可如果我们调用时是以下面的参数类型
报错为 no matching function for call to `func(int&, short int&)'
注意:如果此函数为普通函数的话,编译器会将第二个参数提升为int型的。而这对于模板参数是不会被转换的。
对于上节的函数指针,当出现这样的重载函数时
但有两个例外,编译器会执行转换而不是产生新实例。
1.模板形参是const引用或指针,而实参是相应类型的非const引用或指针,编译器会执行转换
2.当模板形参是非引用类型时,可以执行普通指针性质的转换,数组指针会被当做指向第一个元素的指针,函数指针也是类似。
template <typename T>
func(T para_1, T para_2){
//....
}
template <typename T>
func2(T& para_1, T& para_2){
//....
}
int main(void) { int a[10],b[20];
func(a,b);
func2(a,b);
puts("end in main");
return EXIT_SUCCESS;
}
|
func会调用成功,而func2则会报错。该实参(引用型)不能向指针进行转换。(书上所说)
section16.cpp:32: no matching function for call to `func2(int[10], int[20])'
但是,如果将数组b改为 int b[10],则会无错误,why
可以用函数模板初始化函数指针
int func(const T para_1, const T para_2){
//....
return 1;
}
int (*pf)(const int , const int )=func;
|
函数指针pf所带的参数类型决定了函数模板func的模板参数类型。
函数模板的显示实参:
例如一个简单的求两数和并将结果返回函数
template <typename T,typename S,typename U>
T func4(S para_1, U para_2){
T a=para_1+para_2; return a;
}
|
因为不知道两参数类型,有可能第一个是int,第二个long,也可能相反,故只能选择模板类型的返回值。
但是这样在函数调用时我们没有办法制定 T 类型的实参以使编译器进行参数推断,显式实参在此出现。
long sum= func4<long>(6,7L);
long sum=
func4<long>(6L,7);
|
如此调用就没有问题,显式模板实参以<>括起,其从模板参数最左边第一个开始结合。
在此也可将func4声明为
template <typename T,typename S,typename U>
U func4(T para_1, S para_2){
U a=para_1+para_2;
return a;
}
|
但调用时就得
long sum=
func4<long,int,long>(6L,5);
long sum=
func4<int,long,long>(6,5L)
|
这不是良好的程序设计风格。
template <typename T>
int func5(const T,const T){
//....
return 1;
}
void f6(int (*)(const int ,const int)){}
void f6(int (*)(const double ,const double)){}
|
f6是重载函数,参数是一个函数指针,有两个版本,当我们想用函数模板func5作为实参时
int main(void) {
f6(func5);
return EXIT_SUCCESS;
}
|
编译器报错:
section16.cpp:52: call of overloaded `f6()' is ambiguous
section16.cpp:42: candidates are: void f6(int (*)(int, int))
section16.cpp:43: void f6(int (*)(double, double))
此时我们需要调用时显式指明模板实参
阅读(645) | 评论(0) | 转发(0) |