[C++] 模板与泛型编程(1)

面向对象编程(OOP)和泛型编程都能处理在编写程序时不知道类型的情况。不同之处在于,OOP能处理类型在程序运行之前都未知的情况;而在泛型编程中,在编译时就能获知类型了。

STL中典型的容器、迭代器和算法都是泛型编程的例子。模板是泛型编程的基础。

函数模板

先说明下函数重载,重载就是函数名相同但实参的类型或数量不同的函数的调用。

注意有两种:实参是类型不同或数量不同。(为什么不说形参,因为会有默认值的存在)

如得到一数组中最大值,因为有int和double基本的类型,一个函数无法表达。

这样函数重载中,实现的功能是一样的,但是类型不同。

我们可以通过定义一个函数模板,而不是对每一个类型都定义一个自己的版本。

template<class T>或template<typename T>
return-type sort(...T...)

一个函数模板可以有多个模板参数,也可以有多个基本数据类型,其他的类说明

template<typename T1, typename T2>
void print(T1 arg1, T2 arg2, string s, int k)
{
    cout <<arg1<<s<<arg2<<k<<endl; return ;
}

类模版的定义和声明都以关键字template开头,后面接上以逗号分隔的模版参数表(template parameter list),模版参数表以<>括起来,模版参数一种是类型参数(type parameter),另一种是非类型参数(nontype parameter)。关于类型参数模版不多说了,有关键字class或typename接上后面的标识符构成,例如template template ,对于非类型参数模版(nontype parameter)需要注意的是它由普通参数声明构成的,它代表类模版中的一个常量,例如定义template

tmplate<unsigned N, unsigned M>
int compare(const char (&p1)[N], const char (&p2)[M]){
    return strcmp(p1,p2);
}

但我们调用compare(“hi”,”mom”);时,编译器会用字面值常量的大小来代替N和M,从而实例化模板因此编译器会实例化出如下版本

int compare(const char (&p1)[3], const char (&p2)[4])

一个非类型参数可以是一个整型,或者是一个指向对象或是函数类型的指针或引用。绑定到非类型整型参数的实参必须是一个常量表达式。绑定到指针或引用非类型参数的实参(上面的数组的引用)必须具有静态的生命周期。我们不能用一个普通的(非static)局部变量或动态对象(new出来的)作为指针或引用非类型模板参数的实参。指针参数也可以用nullptr或一个值为0的常量表达式来实例化。

简单来说,整型的非类型模板参数可以当做是全局变量来理解

下面来解释下为什么要使用数组的引用而不是数组

template<class T,int N>
void print(T (&r)[N])
{
    cout<<sizeof(r)<<endl;
    for (int i=0;i<N;++i)
    {
        cout<<r[i]<<",";
    }
    cout<<endl;
}
template<class T,int N>
void print1(T r[N])
{
    cout<<sizeof(r)<<endl;
    for (int i=0;i<N;++i)
    {
        cout<<r[i]<<",";
    }
    cout<<endl;
}
int main()
{    
    int ss[] = {1,2,3,4,5,6,7,8,9};
    print(ss);    
    print1<int,9>(ss);    

    return 0;
}

原因也很简单,传数组名直接给模板时会被当做指针来用,编译器不知道数组的维数,传数组的引用时,编译器则可以推导出数组的维数也就知道了数组的大小了。

模板编译

编译器遇到一个模板定义时,它并不生成代码。只有但我们实例化模板的一个特定版本时,编译器才会生成代码。
当我们调用一个函数时,编译器只需要知道函数的声明。模板则不同,为了生成一个实例化版本,编译器需要掌握函数模板或类模板成员函数的定义。因此,与非模板代码不同,模板的头文件通常包括声明也包括定义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值