当前位置: 首页 > news >正文

机械英语网站免费广告行业网站建设

机械英语网站,免费广告行业网站建设,wordpress 生成 html,做直播网站有市场吗在前面的文章中,我们已经简单的了解了模板的使用,在这篇文章中,我们将继续深入探讨模板 1.模板的特化 1.1 概念 通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果&a…

在前面的文章中,我们已经简单的了解了模板的使用,在这篇文章中,我们将继续深入探讨模板

1.模板的特化

1.1 概念

通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊处理,比如:实现一个专门用来进行小于比较的函数模板

#include <iostream>
using namespace std;
template <class T>
bool LESS(T left, T right)
{return left < right;
}
class date
{
public:date(int year =2025,int month=2,int day=1):_year(year),_month(month),_day(day){}bool operator<(const date& d)const{return (_year < d._year) ||(_year == d._year && _month < d._month) ||(_year == d._year && _month == d._month && _day < d._day);}bool operator>(const date& d)const{return (_year > d._year) ||(_year == d._year && _month > d._month) ||(_year == d._year && _month == d._month && _day > d._day);}
private:int _year;int _month;int _day;
};
int main()
{cout << LESS(1, 2) << endl;       // 可以比较,结果正确cout << LESS(2, 1) << endl;       // 可以比较,结果正确//日期类(自定义类型)也可以date d1(2025, 4, 20);date d2(2025, 1, 7);cout << LESS(d1, d2) << endl;return 0;
}

但是,倘若我们要这样比较,结果就不一定正确了,因为这里我们在比较地址,而不是比较内容本身! 

因此,我们要对模板进行特化, 使得上述例子得以正确执行!

1.2 函数模板特化

函数模板的特化步骤:

1. 必须要先有一个基础的函数模板

2. 关键字template后面接一对空的尖括号<>

3. 函数名后跟一对尖括号,尖括号中指定需要特化的类型

4. 函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪的      错误。

template <class T>
bool LESS(T left, T right)
{return left < right;
}
template<>
bool LESS<date*>(date* left, date* right)
{return *left < *right;
}
int main()
{date d1(2050, 4, 20);date d2(2022, 1, 7);date* p1 = &d1;date* p2 = &d2;cout << LESS(p1, p2) << endl;return 0;
}

 这样,那个指针的例子便可以通过了!因为其将调用特化之后的版本,而不走原来的模板了!

但是,我们之前就学过函数,这样在写一个函数模板,显得多此一举了,不如直接写一个函数,还省事!

bool LESS(date* d1, date* d2)
{return *d1 < *d2;
}
int main()
{date d1(2002, 4, 20);date d2(2022, 1, 7);date* p1 = &d1;date* p2 = &d2;cout << LESS(p1, p2) << endl;return 0;
}

结论:函数模板不建议特化。

1.3 类模板特化

1.3.1 全特化

全特化即是将模板参数列表中所有的参数都确定化

//总的模板
template <class	T1,class T2>
class rens
{
public:rens() { cout << "rens<t1,t2>" << endl; }
private:T1 _r1;T2 _r2;
};
//全特化
template<>
class rens<int*, int*>
{
public:rens() { cout << "rens<int*,int*>" << endl; }
};
template<>
class rens<int, char>
{
public:rens() { cout << "rens<int, char>" << endl; }
//这个私有写不写都行,个人不喜欢写
private:int r1;char r2;
};
template<>
class rens<char, int>
{
public:rens() { cout << "rens<char,int>" << endl; }
//这个私有写不写都行,个人不喜欢写
private:char r1;int r2;
};
int main()
{rens<int, char> r1;rens<int*,int> r2;rens<char, int> r3;rens<int*, int*> r4;return 0;
}

运行结果如下:

结果是这个的原因也不难理解,编译器在选择模板来编译时,一定回去选择最合适的模板来匹配编译! 

1.3.2 偏特化

偏特化:任何针对模版参数进一步进行条件限制设计的特化版本。

其有两种表现方式:一种是将模板参数类表中的一部分参数特化(见第一个偏特化例子),另一种是针对模板参数更进一步的条件限制所设计出来的一个特化版本。
 

template<class t1,class t2>
class rens
{
public:rens() { cout << "rens<t1,t2>" << endl; }
private:t1 _d1;t2 _d2;
};
//偏特化,将模板参数类表中的一部分参数特化
template<class T1>
class rens<T1, int>
{
public:rens(){cout << "rens<T1,int>" << endl;}
//这个东西写不写都行
private:T1 _d1;int _d2;
};
//两个参数偏特化为指针类型
template<class T1,class T2>
class rens<T1*, T2*>
{
public:rens() { cout << "rens<T1*, T2*>" << endl; }
};
//两个参数偏特化为引用类型
template<class T1,class T2>
class rens<T1&, T2&>
{
public:rens() { cout << "rens<T1&, T2&>" << endl; }
};
//两个参数偏特化为指针类型和引用类型
template<class T1, class T2>
class rens<T1*, T2&>
{
public:rens() { cout << "rens<T1*,T2&>" << endl; }
};
int main()
{rens<double, int> r1;rens<int, double> r2;rens<int*, int*> r3;rens<int&, int&>r4;rens<int*, int&>r5;return 0;
}

运行结果:

2.模板分离编译

与普通函数不同,带有模板参数的函数的声明和定义不能分开!否则会报错!!

为此,我们的解决方案是将带模板参数的函数的声明的定义都放在.h文件中,如下图所示:

3.应用

 比如我现在有一个vector容器,现在我们想写一个函数来打印它,那应该怎么办呢?我们有如下几种方式:

一、老老实实的写打印函数

#include<vector>
#include<list>void print(const vector<int>& v)
{vector<int>::const_iterator it = v.begin();     //参数是const vector<int>,所以我们的迭代 器也要用const_iteratorwhile (it != v.end()){cout << *it << " " ;++it;}cout << endl;
}
int main()
{vector<int> v1 = { 1,2,3,4,5,6 };print(v1);return 0;
}

这样写优缺点也很明确,优点是这种写法很简单,看过几遍就会写,缺点是过于死板,如果再让你打印一下double类型或者其他类型,你还得辛辛苦苦去写,太浪费时间,(不过可以适用于摸鱼哈,开玩笑请勿当真!) 为此,我们可以在函数里面加一丢丢模板,这样我们就不必在写double的打印函数了!

二、加模板参数的打印函数

#include<vector>
template <class T>
void print(const vector<T>& v)
{
//	typename vector<T>::const_iterator it = v.begin();     //解释一下这里为什么要加上typename:// 因为vector<T>是一个模板类,// 编译器可能无法自动推断出vector<T>::const_iterator是一个类型,// 因此需要typename明确指出auto it = v.begin();                      //推荐用auto,让编译器自动给我们推导类型while (it != v.end()){cout << *it << " ";++it;}cout << endl;
}
int main()
{vector<int> v1 = { 1,2,3,4,5,6 };print(v1);vector<double> v2 = { 2.2,5.6,9.6,8.3,4.5 };print(v2);return 0;
}

这里有两种方法,一个是用typename关键字,另外一个就是引入c++11的auto类型, 使用auto更加便捷和简洁!

现在,你已经可以打印各种类型的vector了,但是,倘若现在突然让你打印list容器呢?而且我们来不及挨个写了,为此我们再改造一下,使之得以实现!

三、设置一个容器模板

#include<vector>
#include<list>
template<class container>
void print(const container& con)
{//typename container::const_iterator it = con.begin();auto it = con.begin();while (it != con.end()){cout << *it << " ";++it;}cout << endl;	
}int main()
{vector<int> v1 = { 1,2,3,4,5,6 };print(v1);vector<double> v2 = { 2.2,5.6,9.6,8.3,4.5 };print(v2);list<int> l1 = { 1,5,6,9,8,7 };print(l1);list<double> l2 = { 1.1,2.2,3.3 };print(l2);return 0;
}

这样,不论我是vector<int>,还是list<double>,我都可以通过container模板将其替代回去,完成打印的操作! 

4. 模板总结

【优点】

1. 模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生

2. 增强了代码的灵活性

【缺陷】

1. 模板会导致代码膨胀问题,也会导致编译时间变长

2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误

http://www.15wanjia.com/news/191771.html

相关文章:

  • 包头焦点网站建设网站建设导向明确
  • 凡客网站建设家装博览会2023
  • 手机网站制作教程下载全国公路建设市场信用信息管理系统网站
  • 手机做直播官方网站网站tkd优化
  • 银川市网站建设ui设计好找工作吗?
  • 网站后台和移动开发哪些网站是单页面应用程序
  • 虚拟主机网站建设的几个步骤无锡网站制作哪家有名
  • 免费的在线学习网站上海网商电子商务有限公司
  • 4399电脑版网页版入口做搜狗手机网站优化
  • 学网站建设工作室做网站用什么编程语言好
  • 做网站赚广告876游戏平台网页游戏大全
  • 中国建设银行总行官方网站网站的建设服务器
  • 站长工具关键词帝国网站采集管理怎么做
  • 怎么做仲博注册网站手机网站建设软件
  • 2m带宽可以做音乐网站高密 网站建设
  • 用户体验做的好的网站com域名是什么
  • 网站重复页面wordpress教学模板
  • seddog站长之家下载企查查企业查询
  • 南桥做网站哪些网站可以接生意做
  • 网站怎么做下拉刷新做视频上传可以赚钱的网站
  • 市场营销案例分析重庆官网seo技术厂家
  • 建设网站公司哪里好相关的热搜问题重庆美邦 网站建设
  • 建德做网站分享类网站源码
  • 阿里云网站模板 解析wordpress网站顶部加横幅
  • 网站品牌打造廊坊网站建设多少钱
  • 广元网站设计南京有哪些做网站的公司
  • 企业网站 域名注册有哪些建设网站的
  • 秀洲区住房和城乡建设局网站seo关键字优化教程
  • 备案系统网站建设银行网站能不能注销卡
  • 推进门户网站建设方案品牌建设和品牌打造方案