第二章 函数模板 ///max.hpp template <typename T> inline T const& max(T const& a,T const& b) { return a<b?b:a; } ///basics max.cpp #include <iostream> #include <string> #include "max.hpp" int main() { int i = 42; std::cout<<"max(7,i): "<< ::max(7,i)<<std::endl; double f1 = 3.4; double ff2 = -6.7; /// @brief max前的::是为了确认调用的是全局名字空间的max(),而不是标准库的std::max() std::count << "max(f1,f2): "<< ::max(f1,f2) <<std::endl; std::string s1="tanxiaohai"; std::string s2 ="tanhuifang"; std::count<<"max(s1,s2): "<<max(s1,s2)<<std::endl; } 2.3模板参数 函数模板有两种类型参数: 1.模板参数:位于模板名称的前面,在一对尖括号内部进行声明: template <typename T> 2.调用参数:位于函数模板后面,用圆括号进行声明 max(T const& a,T const& b) 解决不同类型的多参数: (1) 可定义任意数量且不同类型的模板参数: template <typename T1,typename T2 ...> (2) 函数模板的实参演绎: template <typename T> inline T const& max(T const& a,T const & b); max<double>(4,4.2) (3) 显示指定模板实参: template <typename T1,typename T2,typename T3> inline T3 max(T1 const& a,T2 const& b) 2.4重载函数模板 重载解析可以看成是函数调用整个完整处理过程的一部分。 对函数调用的处理方法: 1.查找名称,形成初始的重载集。 2.有必要时对集合进行修改,(模板演绎) 3.删除不匹配的候选函数,得到可行的候选函数集。 4.执行重载解析来寻找最佳候选函数,找到即是最佳候选函数,否则为二义性。 5.检查最佳的候选函数。 最佳匹配到最差匹配: 1.完美匹配。参数类型和实参的类型相同,或参数的类型是指向实参类型的引用。 2.有细微调整匹配。如数组转变、或添加const,让类型int**的实参匹配类型为int const* const*. 3.发生提升的匹配。是一种隐式类型转换,把占位少的整数转为占位多的类型。如bool、char、short转为int、unsigned int、long、unsigned long等,float到double 4.发生标准转型(类型转换)的匹配。 5.发生用户自定义转型的匹配。允许任何种类的隐式类型转换。 6.和省略号匹配。省略号参数可以匹配任何类型。 对于T类型的右值,T和Tconst& 的匹配程度一样。 对于T类型的左值,T和T&的匹配程度一样。 非模板优先。 指针转型: 1.任意标准转型都要优于bool 2.从派生类指针到基类指针的转型优于到void*。 3.函数的转型涉及到类继承体系中的多个类,优先选择派生路径最短的转型。 |
|