1.编写泛型程序
//返回两个数的较大者
T bigger(T v1,T v2)
{
return v1>v2?v1:v2; //这里的模板假设元素具有比较性
}
class A
{
} ;
int main()
{
A a,b;
//bigger(a,b);//error, no match for 'operator>' in 'v1 > v2'
cout<<bigger(1,2)<<endl;//2, ok
return 0;
}
2.模板实参推断
*多个类型形参的实参必须完全匹配
template<class T>
//返回两个数的较大者
T bigger(T v1,T v2)
{
return v1>v2?v1:v2; //这里的模板假设元素的类型相同
}
int main()
{
cout<<bigger(1,2.0)<<endl;//error, no matching function for call to 'bigger(int, double)'
return 0;
}
解决办法:bigger函数模板应使用两个类型形参来定义
Example:
template<class T1,class T2>
//返回两个数的较大者
T1 bigger(T1 v1,T2 v2)
{
return v1>v2?v1:v2;
}
int main()
{
cout<<bigger(1,2.0)<<endl;//2 ok
return 0;
}
3.模板类型形参的实参的受限转换
*接受const引用或const指针的函数可以分别用非const对象的引用或指针来调用
Example:
先复习关于const的相关知识
int main()
{
int a=1;
const int b=a;//ok,把a的值复制给b,所以a是否为const并不重要
const int& c=a;//ok,c为a的const引用,此时将不能通过c该变a的值
//b=2;//error,assignment of read-only variable 'b'
//c=2;//error, assignment of read-only reference 'c'
return 0;
}
template<class T>
//返回两个数的较大者
T bigger(const T v1,const T v2)
{
return v1>v2?v1:v2;
}
template<class T>
//返回两个数的较大者
T bigger_ref(const T& v1,const T& v2)
{
return v1>v2?v1:v2;
}
int main()
{
int a=1;
const int b=2;
cout<<bigger(a,b)<<endl;//2,虽然a,b类型不匹配,但调用也是合法的
cout<<bigger_ref(a,b)<<endl;//2
return 0;
}
*数组或函数到指针的转换
如果模板形参不是引用类型,则对数组或函数类型的实参应用常规指针转换
Example:
template<class T>
T fun(const T v1,const T v2);
template<class T>
T fun_ref(const T& v1,const T& v2);
int main()
{
int arr1[]={1,2,3};
int arr2[]={4,5,6};
cout<<fun(arr1,arr2)<<endl;//ok,calls fun(int*,int*)
cout<<fun_ref(arr1,arr2)<<endl;// error,no matching function for call to 'fun_ref(int [3], int [3])'
return 0;
}
T add(T v1,double v2 )
{
return v1+v2;
}
int main()
{
cout<<add(1,1.1)<<endl;//2
cout<<add(1.1,1)<<endl;//2.1
return 0;
}
T add(T v1,T v2 )
{
return v1+v2;
}
int main()
{
int (*pf)(int,int)=add;
int res=(*pf)(1,2);
cout<<res<<endl;//3
return 0;
}
*模板代码总是要对将要使用的类型做一些假设,所以实例化的版本可能是非法的
Example:
template<class T>//返回两个数的较大者
T bigger(T v1,T v2)
{
return v1>v2?v1:v2; //这里的模板假设元素具有比较性
}
class A
{
} ;
int main()
{
A a,b;
//bigger(a,b);//error, no match for 'operator>' in 'v1 > v2'
cout<<bigger(1,2)<<endl;//2, ok
return 0;
}
2.模板实参推断
*多个类型形参的实参必须完全匹配
template<class T>
//返回两个数的较大者
T bigger(T v1,T v2)
{
return v1>v2?v1:v2; //这里的模板假设元素的类型相同
}
int main()
{
cout<<bigger(1,2.0)<<endl;//error, no matching function for call to 'bigger(int, double)'
return 0;
}
解决办法:bigger函数模板应使用两个类型形参来定义
Example:
template<class T1,class T2>
//返回两个数的较大者
T1 bigger(T1 v1,T2 v2)
{
return v1>v2?v1:v2;
}
int main()
{
cout<<bigger(1,2.0)<<endl;//2 ok
return 0;
}
3.模板类型形参的实参的受限转换
*接受const引用或const指针的函数可以分别用非const对象的引用或指针来调用
Example:
先复习关于const的相关知识
int main()
{
int a=1;
const int b=a;//ok,把a的值复制给b,所以a是否为const并不重要
const int& c=a;//ok,c为a的const引用,此时将不能通过c该变a的值
//b=2;//error,assignment of read-only variable 'b'
//c=2;//error, assignment of read-only reference 'c'
return 0;
}
template<class T>
//返回两个数的较大者
T bigger(const T v1,const T v2)
{
return v1>v2?v1:v2;
}
template<class T>
//返回两个数的较大者
T bigger_ref(const T& v1,const T& v2)
{
return v1>v2?v1:v2;
}
int main()
{
int a=1;
const int b=2;
cout<<bigger(a,b)<<endl;//2,虽然a,b类型不匹配,但调用也是合法的
cout<<bigger_ref(a,b)<<endl;//2
return 0;
}
*数组或函数到指针的转换
如果模板形参不是引用类型,则对数组或函数类型的实参应用常规指针转换
Example:
template<class T>
T fun(const T v1,const T v2);
template<class T>
T fun_ref(const T& v1,const T& v2);
int main()
{
int arr1[]={1,2,3};
int arr2[]={4,5,6};
cout<<fun(arr1,arr2)<<endl;//ok,calls fun(int*,int*)
cout<<fun_ref(arr1,arr2)<<endl;// error,no matching function for call to 'fun_ref(int [3], int [3])'
return 0;
}
4.非模板实参的常规转换
*普通类型定义的形参可以使用常规转换
Example:
template<class T>T add(T v1,double v2 )
{
return v1+v2;
}
int main()
{
cout<<add(1,1.1)<<endl;//2
cout<<add(1.1,1)<<endl;//2.1
return 0;
}
5.模板实参推断与函数指针
*函数模板对函数指针进行初始化或赋值时,编译器使用指针的类型实例化具有适当模板实参的模板版本
Example:
T add(T v1,T v2 )
{
return v1+v2;
}
int main()
{
int (*pf)(int,int)=add;
int res=(*pf)(1,2);
cout<<res<<endl;//3
return 0;
}