模板进阶——模板实参推断
一、关键点
模板实参:模板参数T的实例类型,如int、string等
模板实参推断:从函数实参来确定模板实参的过程
模板类型参数与类型转换:const的转换、数组/函数到指针的转换
显式模板实参:当模板参数类型并未出现在函数参数列表时
通过函数指针推断模板实参:函数指针的类型决定了模板实参的类型
二、模板类型参数可以运用的类型转换
template <typename T> void func1(T, T); template <typename T> void func2(const T&, const T&); int main() { string s1 = "hello"; const string s2 = "aloha"; func1(s1, s2); //s2的顶层const将被忽略,调用func1(string, string) func2(s1, s2); //将s1转换为const是允许的,调用func2(const string&, const string&) int a[5], b[10]; func1(a, b); //调用func1(int*, int*) func2(a, b); //错误:形参是引用,数组不会转换为指针 }
小结:顶层const无论是在形参中还是在实参中,都会被忽略
小结:允许将一个非const对象的引用(或指针)传递给一个const对象的引用或指针
小结:如果函数参数不是引用类型,则可以对数组或函数类型的实参应用正常的指针转换
注:函数参数列表中的正常类型的类型转换不受模板影响
三、函数模板显式实参
1. 编译器无法推断出模板实参的情况:
template <typename T1, typename T2, typename T3> T1 sum(T2, T3); //T1的类型无法判断 auto ans = sum<long>(2, 3.14); //T1显式指定为long
注:显示模板实参按由左至右的顺序与对应的模板参数匹配
注:只有右边的显式模板参数可以省略(如T2、T3,它们可以从函数参数推断出来)
2. 正常类型转换可以应用于显式指定的实参
template <typename T> bool cmp(const T&, const T&); int main() { long a; compare(a, 1024); //错误 compare<int>(a, 1024); //a被转换为int compare<long>(a, 1024); //1024被转换为long }