#include<iostream>template<typenameT>Tmax(Tx,Ty){return(x>y)?x:y;}intmain(){std::cout<<max<int>(1,2)<<'\n';// instantiates and calls function max<int>(int, int)return0;}
实例化函数的过程很简单:编译器基本上是克隆函数模板,并用实际类型( int )替换模板类型(T )。
因此,当我们调用max<int>(1,2) 时,被实例化的函数看起来像这样:
12345
template<>// ignore this for nowintmax<int>(intx,inty)// the generated function max<int>(int, int){return(x>y)?x:y;}
下面是与上面相同的示例,显示了编译器在所有实例化完成后实际编译的内容:
1 2 3 4 5 6 7 8 9101112131415161718
#include<iostream>// a declaration for our function template (we don't need the definition any more)template<typenameT>Tmax(Tx,Ty);template<>intmax<int>(intx,inty)// the generated function max<int>(int, int){return(x>y)?x:y;}intmain(){std::cout<<max<int>(1,2)<<'\n';// instantiates and calls function max<int>(int, int)return0;}
#include<iostream>template<typenameT>Tmax(Tx,Ty)// function template for max(T, T){return(x>y)?x:y;}intmain(){std::cout<<max<int>(1,2)<<'\n';// instantiates and calls function max<int>(int, int)std::cout<<max<int>(4,3)<<'\n';// calls already instantiated function max<int>(int, int)std::cout<<max<double>(1,2)<<'\n';// instantiates and calls function max<double>(double, double)return0;}
这与前面的例子类似,但是我们的函数模板这次将用于生成两个函数:一次将 T 替换为int ,另一次将 T 替换为 double 。在所有实例化之后,程序看起来像这样:
#include<iostream>// a declaration for our function template (we don't need the definition any more)template<typenameT>Tmax(Tx,Ty);template<>intmax<int>(intx,inty)// the generated function max<int>(int, int){return(x>y)?x:y;}template<>doublemax<double>(doublex,doubley)// the generated function max<double>(double, double){return(x>y)?x:y;}intmain(){std::cout<<max<int>(1,2)<<'\n';// instantiates and calls function max<int>(int, int)std::cout<<max<int>(4,3)<<'\n';// calls already instantiated function max<int>(int, int)std::cout<<max<double>(1,2)<<'\n';// instantiates and calls function max<double>(double, double)return0;}
需要注意的是:当实例化 max<double> 时,其实参类型为 double。因为我们提供的是实参是 int ,所以它会被隐式类型转换为 double。
模板参数推断
在大多数情况下,我们希望用于实例化的实际类型将与函数形参的类型匹配。例如:
1
std::cout<<max<int>(1,2)<<'\n';// specifying we want to call max<int>
template<typenameT>intsomeFcn(Tx,doubley){return5;}intmain(){someFcn(1,3.4);// matches someFcn(int, double)someFcn(1,3.4f);// matches someFcn(int, double) -- the float is promoted to a doublesomeFcn(1.2,3.4);// matches someFcn(double, double)someFcn(1.2f,3.4);// matches someFcn(float, double)someFcn(1.2f,3.4f);// matches someFcn(float, double) -- the float is promoted to a doublereturn0;}
#include"Max.h" // import template definition for max<T, T>()#include<iostream>voidfoo(){std::cout<<max(3,2);}
main.cpp
1 2 3 4 5 6 7 8 9101112
#include"Max.h" // import template definition for max<T, T>()#include<iostream>voidfoo();// forward declaration for function foointmain(){std::cout<<max(3,5);foo();return0;}