模板与泛型编程(三)--《C++ primer》

前面已经知道,对于函数模板,编译器利用调用中的函数实参来确定其模板参数。那么下面简单讲述一下模板实参推断。


模板实参推断:从函数实参来确定模板实参的过程称为模板实参推断在模板实参推断过程中,编译器使用函数中的实参类型来寻找模板实参,用这些模板实参生成的函数版本与给定的函数调用最为匹配。


与非模板函数一样,在一次调用中传递给函数模板的实参被用来初始化对应函数的形参。若该函数使用模板类型参数,那它采用特殊初始化规则,编译器通常不会对实参进行类型转换,而是生成一个新的模板实例。如

long s1,s2;
int i1,i2;

Compare(i1,i2); 
Compare(s1,s2);  
 

此处Compare()函数使用的是模板类型的参数,各自声明两个类型的变量,当分别调用Compare()函数时,编译器会生成两个模板以便对应匹配相应调用,而不会对s1,s2进行类型转换,进而只生成一个模板。

编译器一般支持两种类型的转换

1、const转换:可以将一个非const对象的引用(或指针)传递给一个const的引用(或指针)形参。(注:反之不可以)

template <class T>
void example(const T &x,const T &y){}
template <class T>
void example1 (T &x,T &y){}
template <class T>
void example2 (T x, T y) {}
 
int main()
{
    const int x=3;
    int y=6;
    example(x,y);
    example1(x,y); /*不能将const转化非const*/
    example2(x,y); /*函数接收非引用类型,形参类型和实例都忽略const*/ 
}


声明且定义两个变量x,y,将x声明为const类型,则在调用example()模板函数时,可以将实参转换位const类型,但是不可以将非const类型的实参变量转换为非const类型变量,如example1()的调用就是错的。


2、数组或函数指针转换:如果函数形参不是引用类型,则可以对数组或函数类型的实参应用正常的指针转换。一个数组实参可以可以转换为一个指向其首元素的指针。类似的,一个函数实参可以转换为一个该函数类型的指针。如

template <class T>
void test (const T a,const T b){}

template <class T>
void test1 (T &a,T &b){}

int main()
{
    int a[10],b[12];
 
    example(a,b);
    example1(a,b);    /*error*/
} 

对于函数,可以使用函数模板对函数指针进行初始化和赋值,如

template <class T> 
int example(const T&,constT&);

int (*p)(const int &,const int &)=example;

p的类型是一个指针,指向"接收2个constint&形参并返回int值的函数",形参的类型决定了T的模板实参的类型,T的模板实参为int型,指针p引用的是将T绑定到int的实例化。


函数模板的显式实参

某些情况下,编译器无法推断模板实参的类型(例如  当希望允许用户控制模块实例化,当函数的返回值必须与形参列表中所用的所有类型都不同时)

指定显式模板实参

解决办法可以是定义表示返回类型的第三个模板参数,从而用户控制返回类型,如

template <class T1,class T2,class T3>
T1 example(T2 &x,T3 &y){}

double x=7.5; 
int y=4;

example<int>(x,y)    /*T1:int T2:double T3:int*/

没有任何函数实参的类型可用来推断T1的类型。每次调用example时调用者必须为T1提供一个显示模板实参。


template <class T>
int Compare(const T &x,const T &y)
{
    if (x==y) 
      return 0;
    return (x>y)?1:-1;
}

void example(int (*p)(const string &,const string &)){}

void example(int (*p)(const int &,const int &)){}
 
void main()
{
    example(Compare<int>);
    example(Compare<string>);
} 

声明模板Compare函数,example函数通过显式指定函数类型分别来调用Compare模板函数,生成不同类型的Compare模板函数,从而实现了用户指定使用类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值