1.template参数定义中,typename 和class 可以互换,尽量使用typename,不可以使用struct
2.模板参数可以使用任意类型,包括内置类型,自定义类,枚举等
3.模板参数名称可以使用任意名称
4.函数模板不是只编译一份满足多重需要,而是为每一种实例化类型编译一份
5.只有函数模板的使用才会引发实例化
6.为某种类型实例化模板,而此类型不完全支持模板内使用的操作会引发编译错误
7.每种模板会编译两次:1.如果没有用户请求实例化则只做语法检查
2.当用户请求实例化时,模板进行检查确保所有的调用都有效
2.2 实参推演
1.函数模板根据传递的参数类型进行推演
2.自动类型转换不被允许 解决方法:1.显式指定类型
2.cast
3.使用多参数模板
2.3 模板形参
1.函数模板有两种参数 1.模板形参,声明在函数名字前的尖括号里 template<typename T>
2.调用形参,声明在函数名后面的圆括号里 set(T value)
2.类模板可以设置默认模板实参,函数模板不可以
3.可以使用任意数量的模板参数
4.模板参数之间进行转换可能会产生临时对象导致不能返回引用
5.调用形参和模板形参之间的关系叫做函数模板实参推演6.可以显式地指定参数类型,而当调用形参和模板形参之间没有关系或者模板形参不能被决定的话,必须显式地指定参数类型
7.模板实参推演不进行返回值匹配
8.可以部分地显式指定不能通过推演得到的模板参数(放在template<>开始部分)
2.4 重载函数模板
1.普通(非模板)函数重载过程:
注意: 1.通过函数指针和指向成员函数的指针调用的函数不参与重载决定过程
因为它们是在运行时刻通过指针决定调用的 [Page]
2.类函数宏不参与重载决定过程
1.查找函数名构造重载集合
2.集合里的函数尽量以各种方式进行变换,例如参数推演,隐式转换等以便匹配调用
3.变换完成后不能匹配的被从集合里面删除,剩下的构成一个可行函数候选集合
4.进行最优匹配,如果找到最优的,选中它;如果没有最优的,则此调用是不明确的
5.检查选中的函数。如果是类似于私有成员函数这种不能到达的,那么发出一个警告
*其中4:
1.完美匹配 参数类型和表达式一致,或提及到表达式类型比如加const/volatile限定符
2.次要调整后匹配:比如数组变量退化成指针,或给类型添加const等
3.提升后匹配 把小整型(bool char short)转化成int long uint ulong, float 转化成double等
4.标准转换后匹配 比如int到float,不包括对于转换操作符或转换构造函数的隐式调用
5.用户定义转换后匹配 允许任何隐式转换
6.加上省略号后匹配 基本可以匹配任何类型,但是non-pod class 会导致未定义行为
省略一部分
重载细节: 1.非模板函数优于模板函数实例(不管是产生自一般实例还是显式特化)
2.特化地更多的模板实例优先
转换顺序: 上述*处的反向转换
省略一部分
2.重载函数模板
1.非模板函数可以和函数模板名字相同,类型和返回值相同
2.其他条件相同, 非模板函数优于模板函数实例
3.空模板参数调用函数要求使用模板函数实例,且所有类型都要从实参中推演出来
4.模板参数不允许类型转换
5.多参数函数模板各参数之间转换可能会产生临时对象
6.确保所有重载的函数模板都在被调用之前可见
2.5 总结
函数模板定义一系列带有不同模板参数的函数
传递参数给模板的时候,函数模板才被实例化
可以显式指定模板参数
可以重载模板参数
重载函数模板时,使用显式指定来限制改变
确保所有重载的函数模板在被调用之前都可见