函数模板与模板的特例化

本文详细解释了C++中的函数模板,包括模板参数的类型化、函数模板的实例化过程,以及如何通过特例化处理不同类型的参数。同时介绍了模板的非类型参数及其应用。
摘要由CSDN通过智能技术生成

函数模板

模板的意义:对类型进行参数化

模板类型参数

c++使用class、typename关键字定义模板类型参数

  • 函数模板:不进行编译,因为类型还不知道
template <typename T>//定义一个模板参数列表
bool compare(T a,T b)//compare是一个函数模板
{
    cout<<"template compare"<<endl;
    return a>b;
}
  • 函数模板的实例化:从函数调用点开始进行实例化
    • compare<int>是函数名
    • compare只是模板名称
    • 故下述代码是对compare<int>函数的调用
compare<int>(1,2);
  • 模板函数:函数模板被实例化后的模板函数,才是要被编译器所编译的
    /*
    模板函数:在函数调用点,编译器用用户指定的类型,从原模板实例化一份函数代码出来
    bool compare(int a,int b)
    {
        cout<<"template compare"<<endl;
        return a>b;
    }
    */
  • 模板的实参推演:根据用户传入参数的实参类型,来推导出模板类型参数的具体类型

    //模板的实参推演
    compare(3,4);

完整代码

template <typename T>//定义一个模板参数列表
bool compare(T a,T b)//compare是一个函数模板
{
    cout<<"template compare"<<endl;
    return a>b;
}

void test()
{
    compare<int>(1,2);
    /*
    模板函数:在函数调用点,编译器用用户指定的类型,从原模板实例化一份函数代码出来
    bool compare(int a,int b)
    {
        cout<<"template compare"<<endl;
        return a>b;
    }
    */
    compare<double>(3.4,2.1);
    /*
    bool compare(double a,double b)
    {
        cout<<"template compare"<<endl;
        return a>b;
    }
    */

    //模板的实参推演
    compare(3,4);
}

模板的特例化

void test()
{
    compare("aaa","bbb");
    /*实例化后的模板函数
    bool compare(const char* a,const char* b)//compare是一个函数模板
    {
        cout<<"template compare"<<endl;
        return a>b;
    }
    */
}

 如上代码所示,上述代码实例后的代码运行后显然是错误的,因为对于char*类型的变量来说,其return a>b返回的结果是它们所指向的内存地址的大小关系,而并不是我们想要的ASCII大小,这是因为指针本身就是一个地址值,其大小关系与其指向的内存空间大小关系一致。

如果要比较两个字符串的大小关系,应该使用字符串比较函数(如 strcmp)来进行比较。这些函数将会比较两个字符串的内容,而不是它们对应的指针地址。

我们想要的真正代码应该为:

    
    bool compare(const char* a,const char* b)//compare是一个函数模板
    {
        return strcmp(a>b)>0;
    }
    

因此,对于这种情况,需要对模板进行特例化,可以使得当我们调用char*类型的模板函数。

template <typename T>//定义一个模板参数列表
bool compare(T a,T b)//compare是一个函数模板
{
    cout<<"template compare"<<endl;
    return a>b;
}

//针对compare函数模板,提供const char*类型的特例化版本
template<>
bool compare(const char* a,const char* b)
{
    cout<<"compare<const char*> template"<<endl;
    return strcmp(a,b)>0;
}

测试

void test()
{
    compare(1,2);
    compare("aaa","bbb");
    /*
    bool compare(const char* a,const char* b)//compare是一个函数模板
    {
        cout<<"template compare"<<endl;
        return strcmp(a>b)>0;
    }
    */
}

 

需要注意的是,函数模板的特例化实现前提是必须要有函数模板 

模板非类型参数

模板的非类型参数只能使用,不能修改,必须是整数类型(地址、引用都可)

//T是一个类型参数,SIZE为非类型参数
template <typename T,int SIZE>
void sort(T* arr)
{
    for(int i=0;i<SIZE-1;i++)
    {
        for(int j=0;j<SIZE-1-i;j++)
        {
            if(arr[j]>arr[j+1])
            {
                int tmp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=tmp;
            }
        }
    }
}

测试

void test()
{
    int arr[]={12,5,7,8,9,5,4,6,2,5,3};
    const int size=sizeof(arr)/sizeof(arr[0]);
    sort<int,size>(arr);

    for(int a:arr)
    {
        cout<<a<<" ";
    }
    cout<<endl;
}
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值