C++函数新特性——函数模版

函数模版


函数模版是通用的函数描述,使用泛型来定义函数,其中的泛型可用具体的类型(如int或double)来代替。通过将类型作为参数传递给模版,可使编译器生成该类型的函数。

下面演示一个最简单的函数模版:

//交换两数据的值
template<typename T>
void Swap(T &a, T &b){
    T temp;
    temp = a;
    a = b;
    b = temp;
}

如果采用以下调用:

int a=10;
int b=20;
Swap(a,b);

这将代表调用下面这个函数:

void Swap(int &a, int &b){
    int temp;
    temp = a;
    a = b;
    b = temp;
}

Swap()函数接受了两个int参数,因此编译器生成该函数的int版本,也就是说用int替换所有的T。

调用函数模版必须使用相同的类型,否则模版将无法识别不同的类型而导致编译错误


显式具体化

显式具体化也是基于函数模版的,只不过在函数模版的基础上,添加一个专门针对特定类型的、实现方式不同的具体化函数。

对于有些特殊类型,可能不适合模版实现,需要重新定义实现。此时可以使用显式具体化(explicit specialization)
以上面的Swap()模版为例,假定有如下结构体:

struct job{
    char[20] name;
    double salary;
};

如果采用Swap()函数模版将交换两个结构体。但如果只想交换其中的一部分,比如salary,而不交换name,则可以通过使用显式具体化。

//结构体
struct Job{
    char[20] name;
    double salary;
};

//函数模版
template<typename T>
void Swap(T &a, T &b){
    T temp;
    temp = a;
    a = b;
    b = temp;
}

//显式具体化
templete<> void Swap<Job>(Job &a,Job &b){
    int temp;
    temp = a.salary;
    a.salary = b.salary;
    b.salary = temp;
}

编译器会优先选择显式具体化的版本,交换结构体的salary,而非交换两个结构体。

编译器对三种原型的选择

对于交换结构体Job的非模版函数、函数模版和具体化的原型:

//非模版函数
void Swap(Job &,Job &);
//函数模版
template <typename T>
void Swap(T &,T &);
//显式具体化
template<>void Swap<Job>(Job &,Job &);

在有多个原型时,编译器在选择原型时,非模版版本优先于显式具体化和模版版本,而显式具体化优先于使用模版生成的版本


显式实例化

当显式实例化模版时,在使用模版之前,编辑器根据显式实例化指定的类型生成模版实例。

template void Swap<int>(int&,int&);

显式实例化只需要声明,不需要重新定义。编译器会根据模版来实现实例声明和实例定义。
当然也可以直接调用 Swap<int>(a,b);

显式具体化和显式实例化的区别

//显式具体化
template<>void Swap<Job>(Job &,Job &);
//或
template<>void Swap(Job &,Job &);


//显式实例化
template void Swap<int>(int &,int &);

显式具体化不仅要声明,还要给出定义;
显式实例化只需要声明,不需要给出定义。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值