模板函数和模板类的特例化

「引入原因」

编写单一的模板,它能适应多种类型的需求,使每种类型都具有相同的功能,但对于某种特定类型,如果要实现其特有的功能,单一模板就无法做到,这时就需要模板特例化

「定义」对单一模板提供的一个特殊实例,它将一个或多个模板参数绑定到特定的类型或值上

1)模板函数特例化

必须为原函数模板的每个模板参数都提供实参,且使用关键字template后跟一个空尖括号对<>,表明将原模板的所有模板参数提供实参,举例如下:

template<typename T> //模板函数

int compare(const T &v1,const T &v2)

{

    if(v1 > v2) return -1;

    if(v2 > v1) return 1;

    return 0;

}

//模板特例化,满足针对字符串特定的比较,要提供所有实参,这里只有一个T

template<>

int compare(const char* const &v1,const char* const &v2)

{

    return strcmp(p1,p2);

}

「本质」特例化的本质是实例化一个模板,而非重载它。特例化不影响参数匹配。参数匹配都以最佳匹配为原则。例如,此处如果是compare(3,5),则调用普通的模板,若为compare(“hi”,”haha”)则调用特例化版本(因为这个cosnt char*相对于T,更匹配实参类型),注意二者函数体的语句不一样了,实现不同功能。

「注意」模板及其特例化版本应该声明在同一个头文件中,且所有同名模板的声明应该放在前面,后面放特例化版本。

2)类模板特例化

原理类似函数模板,不过在类中,我们可以对模板进行特例化,也可以对类进行部分特例化。对类进行特例化时,仍然用template<>表示是一个特例化版本,例如:

template<>

class hash<sales_data>

{

    size_t operator()(sales_data& s);

    //里面所有T都换成特例化类型版本sales_data

    //按照最佳匹配原则,若T != sales_data,就用普通类模板,否则,就使用含有特定功能的特例化版本。

};

「类模板的部分特例化」

不必为所有模板参数提供实参,可以指定一部分而非所有模板参数,一个类模板的部分特例化本身仍是一个模板,使用它时还必须为其特例化版本中未指定的模板参数提供实参(特例化时类名一定要和原来的模板相同,只是参数类型不同,按最佳匹配原则,哪个最匹配,就用相应的模板)

「特例化类中的部分成员」

可以特例化类中的部分成员函数而不是整个类,举个例子:

template<typename T>

class Foo

{

    void Bar();

    void Barst(T a)();

};

template<>

void Foo<int>::Bar()

{

    //进行int类型的特例化处理

    cout << "我是int型特例化" << endl;

}

Foo<string> fs;

Foo<int> fi;//使用特例化

fs.Bar();//使用的是普通模板,即Foo<string>::Bar()

fi.Bar();//特例化版本,执行Foo<int>::Bar()

//Foo<string>::Bar()和Foo<int>::Bar()功能不同

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会编程喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值