C++ 模板的原理、应用

.初识:

        C++中模板是泛型编程的基础,所谓泛型编程就是不受参数类型限制、以独立于任何特定类型的方法编写代码,使用泛型程序时,需要提供具体的所操作的类型、值。C++中的STL中的各种容器、迭代器等,都是泛型编程的实例。

 模板定义:

有以下重载的函数,用以比较给定参数的大小,每一个可以比较一种参数的大小

int compare(const string &s1,const string &s2)
{            
    if(s1>s2)
       {
        return 1;
       }
    else if(s1<s2)
    { 
       return -1;
    }
return 0;
}


int compare(const int &n1,const int &n2)
{            
    if(n1>n2)
    {
      return 1;
    }
    else(n1<n2)
    {
     return -1;
    }
 return 0;   
}

可以看出,重载函数的功能一样,只是参数类型不同,若想要比较其他类型,就需要一次次的重载、编写,需要提前将参数的特定类型给出。如果希望函数用于比较未知类型的数据,就不能这样编写了。

由以上的例子,引出函数模板的概念; 

.函数模板:

可以不用为每个特定类型编写一个函数,而是只定义一个”函数模板“,函数模板代表了一个函数家族,在使用时被参数化,根据参数类型产生特定的类型版本,它独立于类型:

/*
compare 的模板
*/

template<typename T>    //模板参数表
int compare(const T &val1,const T &val2)
{            
    if(val1>val2)
    {    
        return 1;
    }else if(val1<val2)
    {        
        return -1;
    }
return 0;
}

 模板的定义以template开头:

template<typaneme T1,typename T2……>

函数

其中,模板参数表中的typename 可以用class 替换,二者在模板中作用一致;

模板形参T1、T2的具体类型由编译器根据所用的函数而决定,一旦编译器确定了实际的参数类型,就称它为实例化了函数模板的一个实例。且模板形参可以是表示类型的类型形参,也可以是表示常量表达式的非类型形参(后续会说到)。

 函数模板的实例化:

 隐式实例化:让编译器根据实参自动推导模板参数的实际类型

template<class T>
T add(const T &l,const T &r)
{        
    return l+r;
}

int main()
{
    add(1.0,1);    //该行不能通过编译,因为两个参数类型不同,编译器推导到的T的类型不同,无法确定其具体类型
   
//处理方式:1.将其中一个参数强转为另一个类型  2.使用显示实例化
return 0;
}

显式实例化:在调用函数时,在函数名后加<>,在其中指定模板参数的类型

int main()
{
add<int>(1.0,1);

return 0;
}

模板函数的匹配原则:

1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函 数,如果普通函数与参数匹配,编译器直接调用,不再特化模板函数。

2. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模 板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板

.模板类的声明;

template<class T>

template<class T1,class T2>

template<typename T1,typename T2>

template<typename T1,class T2>

.测试题:

1.下面有关C++中为什么用模板类的原因:

A.模板可以具有非类型参数,用于指定大小,可以根据指定的大小创建动态结构

B.模板最重要的一点就是类型无关,提高了代码复用性

C.模板运行时不检查数据类型,也不保证类型安全,相当于类型的宏替换,故错误

D.只要支持模板语法,模板的代码就是可移植的

2.在下列对fun的调用中,错误的是( )

template <class T>

T fun(T x,T y){

  return x*x+y*y;

}

A.fun(1, 2)        (正确,参数类型相同,不存在二义性)

B.fun(1.0, 2)        (错误,参数类型不同,函数推导参数时会有二义性)

C.fun(2.0, 1.0)        (正确,类型相同)

D.fun<float>(1, 2.0)   (正确,通过类型实例化函数,调用正确)

3. 下列关于模板的说法正确的是( )

A.模板的实参在任何时候都可以省略        (不一定,在参数类型不同时,需要显示的指定参数类型)

B.类模板与模板类所指的是同一概念        (类模板是泛化的类,模板类是类模板的实例化)

C.类模板的参数必须是虚拟类型的          (C++中类模板的声明格式为template<模板形参表声明><类声明>,并且类模板的成员函数都是模板函数)

D.类模板中的成员函数全是模板函数        (正确)

4.下列描述错误的是( )

A.编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础

B.函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具

C.模板分为函数模板和类模板

D. 模板类跟普通类以一样的,编译器对它的处理时一样的

(编译器对模板类的处理会分别进行两次编译)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值