泛型编程之模板 2

上次写了个Max函数,那么它能用来比较字符串吗?
我们传进 需要去的参数是地址,函数将直接比较两个地址的大小,所以显然不能比较字符串,那么如何让它能够比较字符串呢,我们就需要对模板函数进行特化

1 模板函数特化:有时候我们并不能够写出对所有可能被实例化的模型都合适的模板,有些时候通用模板也有可能处理不了某个特定的类型,这时就需要对模板函数进行特化
现在我们来看特化后的字符串比较函数

template <typename T>
int compare(const T &r, const T &l)
{
    if (r > l)
    {
        return 1;
    }
    else if (r == l)
    {
        return 0;
    }
    else
        return -1;
}
template<>
int compare<const char* &>(const char*&pl, const char* &pr)
{
    return strcmp(pl, pr);
}
int main()
{
    const char* p1 = "123";
    const char* p2 = "456";
    compare(p1, p2);
    compare<const char* &>(p1, p2);
    char* p3 = "222";
    char* p4 = "123";
    compare(p3, p4);
}

看起来是不是非常简单,但是需要注意的地方也不少
1)模板函数的定义形式如下:
关键字template后面跟一对空的< >
模板名<特化定义的模板形参>函数形参表
函数体
eg:template<>
int compare

    eg:template< >
             int compare<int>(int)
             {
             return 0;
             }

b 模板形参表不能少
int compare(int v1,int v2)
{
return 0;
}//这种定义是错误的 ,编译器并不认为它是特化函数

3)现在来看一下特化函数的调用过程(不同的编译器下面的调用方式可能不同,这是在13版下测出的结果)

compare  const <char* &>(p1, p2);

//因为他的参数和特化函数参数列表完全匹配,而且加了特化定义的模板形参所以会调用特化函数
这里写图片描述
compare(p1, p2);//但是在10 版的编译器下面调用的是特化函数
他的函数参数和特化函数参数相同,但是没写特化定义的模板形参,所以它调用的仍然是模板函数
这里写图片描述
它的实参和特化定义的模板函数形参类型不同,所以编译器会根据她的实参推演然后实例化出一个新的模板函数
这里写图片描述
注意
1)在模板特化版本的调用中,实参类型必须与特化版本函数的形参类型完全匹配, 如果不匹配,编译器将为实参模板定义中实例化一个实例。
2)特化不能出现在模板实例的调用之后,应该在头文件中包含模板特化的声明,然 后使用该特化版本的每个源文件包含该头文件。


模板类


之前我们写过顺序表,其中所放的是数字,那么现在如果想要让它可以放置任何类型的数据(int/double/char/float……)该怎么写呢?由于学习过模板函数,我们自然便想到了模板类
1 模板类的定义格式
首先,模板类也是模板,所以必须以关键字template开头
template

当我们进行test1函数调用的时,编译器会分别把T换成int double重新生成函数,
这时我们会突然想那能不能放String呢?
于是我们又定义了一个String类(这个写过很多次,就不再写了)只是我们在调用的时候会发现Seqlist总是会失败,但是自我感觉代码的逻辑是正确的,我们单不调试发现崩溃的总是这一块,代码如下

只看代码,貌似并没有问题,观察一下内存

void CheckCapacity()
    {
        if (_size >= _capacity)
        {
            T*tmp = new T[_capacity * 2];
            memcpy(tmp, _pdata, _capacity*sizeof(T));
            delete[]_pdata;
            _pdata = tmp;
            _capacity *= 2;
        }
    }

这里写图片描述
这里写图片描述
具体原因用画图解释比较清楚,其实也就是memcpy的时候执行了浅拷贝,所以此处应该改成深拷贝
这里写图片描述
代码实现如下

for(int i=0;i<size;i++)
{
  tmp[i]=_pdata[i];
  }
  delete []_pdata;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值