一:定义模板
eg:template <typename T> //template 可以用class替换
inline T const& max (T const& a,T const& b )
{ return a<b?b:a; }
二:使用模板
eg:#include <iostream>
#include <string>
#include "max.h"
using namespace std;
int main()
{
int i=42;
cout<<"max(7,i):"<<max1(7,i)<<endl;
double f1=3.4;
double f2=6.7;
cout<<"max(f1,f2):"<<max1(f1,f2)<<endl;
string s1="wang";
string s2="nihao";
cout<<"max(s1,s2):"<<max1(s1,s2)<<endl;
return 0;
}
如果试图基于一个不支持模板内部所使用操作的类型实例化一个模板,那么将会导致一个编译错误,我们可以得出这样一个结论:模板被编译了两次,分别发生在 一是实例化以前,先检查模板代码本身买查看语法是否正确,在这里会发现错误的语法;二是在实例化期间,检查模板代码,查看是否所有的调用都有效,在这里会发现无效的调用,例如该实例化类型不支持某项函数的调用等(这不同于普通函数中的编译和链接之间的区别,因为对于普通函数而言,只要该函数的声明(即不需要定义),就可以顺利通过编译)。
三:模板实参的演绎
eg: max(4,7) //ok
max(4,4.2) //error 函数模板参数的实例化中其数据不能进行自动转换
有三种方法可以用于处理上面的这个错误:
1、对实参进行强制类型转换,是它们可以相互匹配
2、显式指定(或者限定)T的类型:max(static_cast<double>(4),4.2)
(当模板参数和调用参数没有发生关联,或者不能由调用参数来决定模板参数的时候,在调用时就必须显式指定模板参数)
3、指定两个参数可以具有不同的类型
四:重载函数模板
template <typename T>
inline T const& max (T const& a,T const& b,T const& c)
{
return ::max(::max(a,b),c);
}
int main()
{
::max(7,42,68);
max<>(7,42); //可以显式的指定一个空的模板参数表,这个语法好像是告诉编译器,只有模板才能匹配这个调用。
::max('a','b');
::max('a',42.7);
return 0;
}
五:小结
模板函数为不同的模板实参定义了一个函数家族;
当你传递模板参数的时候,可以根据实参的类型来对函数模板进行实例化。
你可以显示的指定模板参数。
你可以重载函数模板
当重载函数模板的时候,把你改变限制在显式地指定模板参数。
一定要让函数模板的所有重载版本的声明都位于他们被调用的位置之前。