//主模板
template <typename T>
class Heap
{
private:
std::vector<T> h_;
public:
void push(const T& val);
T pop();
bool empty() const //const声明在末尾表示该函数不能修改类变量
{
return h_.empty();
}
}
template <typename T>
void Heap<T>::push(const T& val)
{
h_.push_back(val);
std::push_heap(h_.begin(),h_.end());
}
template <typename T>
T Head<T>::pop()
{
std::pop_head(h_.begin(),h_.end());
T tmp(h_.back());
h_.pop_back();
return tmp;
}
//显示特化版本
/***********************************************
* 可以看到模板参数列表是空的,其实这根本不是一个模
* 板. 因为没有指定任何模板参数.所以模板的显式特化又被
* 称作"完全特化".
* Heap<const char*> 完全特化,不会导致模板的实例化;
* Heap<int> 特化,会导致模板的实例化;
* 编译器根据主模板的声明来检查类模板特化.
***********************************************/
template<>//注意,无任何参数,当然,它本来就不是一个模板
class Head<const char *>
{
private:
std::vector<const char *> h_;
public:
void push(const char *pval);
const char * pop();
bool empty() const //const声明在末尾表示该函数不能修改类变量
{
return h_.empty();
}
};
//再次提醒, Head<const char *>不是一个模板
void Heap<const char*>::push(const char *pval)
{
h_.push_back(pval);
std::push_heap(h_.begin(),h_.end());
}
/***********************************************
* C++没有要求显式特化的接口必须和主模板的接口完全
* 匹配.如该例中,没有定义主模板的empty函数,并且自行增加
* 了size和capitalize两个函数.
* 提醒:此例中不定义empty函数是不可取的,定义模板的
* 显式特化和类的派生之间虽然不存在任何技术上的联系,但
* 是用户依然可以参考类的派生的优点,让特化版本至少具有
* 主模板的基本能力.
***********************************************/
template<>//注意,无任何参数,当然,它本来就不是一个模板
class Head<char *>
{
private:
std::vector<char *> h_;
public:
void push(char *pval);
char * pop();
//注意,此处没有提供empty函数哟!!!
size_t size() const;
void capitalize();
};
/***********************************************
* 局部特化
* 和完全特化不同,这里的Heap参数类型只是被部分的确
* 定为T*,而T是一个未指定的类型,这就是为什么说它是局部
* 特化的原因;
* 当使用一个未经任何修饰的指针类型来实例化Heap时,
* 局部特化将优先于主模板;
* 当使用const char * 或 char *(参考类模板显式特化)来
* 实例化Heap时,此时完全特化又会优先于局部特化.
* Heap<std::string> h1; 主模板 T是std::string
* Heap<std::string *> h2; 局部特化 T是std:string
* Heap<int **> h3; 局部特化 T是int *
* Heap<char *> h4; 完全特化 T是char *
* Heap<const int *> h5; 局部特化 T是const int
* Heap<int (*)()> h6; 局部特化 T是int()
***********************************************/
template <typename T>
class Heap<T *> //注意这里
{
private:
std::vector<T *>h_;
public:
void push(const T *val);
T *pop();
bool empty()
{
return h_.empty();
}
};
template <typename T>
void Heap<T *>::push(const T *val)
{
//......
}
/***********************************************
* 有一点很微妙但很有用:主模板的完全特化或局部特化
* 必须采用与主模板相同数量和类型的实参进行实例化,但它
* 的模板的参数并不需要具有和主模板相同的形式.
***********************************************/
//定义一个模板,有三个模板参数,书写形式如下
template <typename R,typename A1,typename A2>
//注意,局部特化中,模板参数也是三个,但书写形式可不一样喽
class Heap<R (*) (A1,A2)>
{
//......
};
Heap<char *(*) (int,int)> h7; //R是char *,A1和A2是int
//把 char *(*) (int,int) 想象成一个"指向有两个参数的非成员函数的指针"
template <class C,typename T>
class Heap<T C::*>
{
//......
};
Heap<std::string Name::*> h8;//T是string,C是Name
//主模板
template <typename T>
class Heap
{
private:
std::vector<T> h_;
public:
void push(const T& val);
T pop();
bool empty() const //const声明在末尾表示该函数不能修改类变量
{
return h_.empty();
}
}
//其实我们真正需要特化的是 push 和 pop两个函数.
//对比显式特化,它是通过主模板,再写一个模板显式特化版本类;
//而这里只是对类模板成员进行了单独特化.
template<>
void Heap<const char*>::push(const char *const &pval)
{
h_.push_back(pval);
std::push_heap(h_.begin(),h_.end(),strLess);
}
template<>
const char* Heap<const char*>::pop()
{
std:pop_heap(h_.begin(),h_end(),strLess);
const char* tmp = h_.back();
h_.pop_back();
return tmp;
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-3 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2026 源码网商城 (www.yuanmawang.com) 版权所有