oop &&GP 模板 ---> 特化和偏特化
OOP面向对象编程
GP泛型编程(generic programming)
两者的主要区别就是OOP将数据和对数据的操作放在一起,
GP就是将数据和操作独立开来
GP: 数据就是container进行存储,操作就是函数,也就是最数据操作的算法,container和algorithn都可以各自闭门造车,之间通过iteration联通就可以了
比如说sort
sort(begin,end,cmp)
algorithm通过iteration操作确定范围,并通过iteration来取出contain中的数据
大家可以看一下钱的stl六大部件中的那张六大部件的关系图
为什么list不能使用sort(没有内置sort)
list《int》ls
ls.sort()错误
sort内部的源码中cmp那里有first+(last-first)/2
也就是对迭代器不定数量的偏移,如果想要这样操作,那么操作的数据在内存中的位置一定是连续的
但是list存储的链表吗,链表每一个元素所占的地址不是连续的,我们在操作list的时候可以通过迭代器一个一个的进行偏移,但是不能偏移多个,因为地址不是连续,所以内部也就不能使用sort
random access iterator
所有algorithm,其内部设计元素本身的操作,无非就是比大小
8**************************************************************************************************
模板
一:模板有函数模板和类模板
类模板很常见了,我们使用的stl都需要使用类模板,类模板需要《type》去指定类型,这是为了告诉编译器类型,否则编译器没有线索去判断什么类型

上面这张图是函数函数min,首先我们定义了stone的两个对象,之后我们使用min模板函数,这个时候编译器做了一件非常棒的事情,就是编译器对函数模板进行了实参类型的推导,编译器会看他的参数r1,找到上一行,发现是stone类型的,如果min中的T就是stone类型了,之后min要进行操作,编译器进入min后走到<的时候,首先他作用于<左边的参数,并到T类型中查看时候与<的重载,发现在stone类中确实有重载,编译器于是走到operator中,发现是按到weight比较的,于是执行
二:成员模板
不重要
类模板又有特化,和偏特化,偏特化又有个数上的偏和范围上的偏
模板特化
有时为了需要,针对特定的类型,需要对模板进行特化,也就是所谓的特殊处理。比如有以下的一段代码:
#include <iostream>
using namespace std; template <class T>
class TClass
{
public:
bool Equal(const T& arg, const T& arg1);
}; template <class T>
bool TClass<T>::Equal(const T& arg, const T& arg1)
{
return (arg == arg1);
} int main()
{
TClass<int> obj;
cout<<obj.Equal(, )<<endl;
cout<<obj.Equal(, )<<endl;
}
类里面就包括一个Equal方法,用来比较两个参数是否相等;上面的代码运行没有任何问题;但是,你有没有想过,在实际开发中是万万不能这样写的,对于float类型或者double的参数,绝对不能直接使用“==”符号进行判断。所以,对于float或者double类型,我们需要进行特殊处理,处理如下:
#include <iostream>
using namespace std; template <class T>
class Compare
{
public:
bool IsEqual(const T& arg, const T& arg1);
}; // 已经不具有template的意思了,已经明确为float了
template <>
class Compare<float>
{
public:
bool IsEqual(const float& arg, const float& arg1);
}; // 已经不具有template的意思了,已经明确为double了
template <>
class Compare<double>
{
public:
bool IsEqual(const double& arg, const double& arg1);
}; template <class T>
bool Compare<T>::IsEqual(const T& arg, const T& arg1)
{
cout<<"Call Compare<T>::IsEqual"<<endl;
return (arg == arg1);
} bool Compare<float>::IsEqual(const float& arg, const float& arg1)
{
cout<<"Call Compare<float>::IsEqual"<<endl;
return (abs(arg - arg1) < 10e-);
} bool Compare<double>::IsEqual(const double& arg, const double& arg1)
{
cout<<"Call Compare<double>::IsEqual"<<endl;
return (abs(arg - arg1) < 10e-);
} int main()
{
Compare<int> obj;
Compare<float> obj1;
Compare<double> obj2;
cout<<obj.IsEqual(, )<<endl;
cout<<obj1.IsEqual(2.003, 2.002)<<endl;
cout<<obj2.IsEqual(3.000002, 3.0000021)<<endl;
}
注意一个问题就是
20 template <>
21 class Compare<double>
22 {
23 public:
24 bool IsEqual(const double& arg, const double& arg1);
25 }; 注意对于特化一定要是带有空的<>的,注意格式的问题,和正常的模板类有很大的不用结构问题
模板偏特化
上面对模板的特化进行了总结。那模板的偏特化呢?所谓的偏特化是指提供另一份template定义式,而其本身仍为templatized;也就是说,针对template参数更进一步的条件限制所设计出来的一个特化版本。这种偏特化的应用在STL中是随处可见的。比如:
template <class _Iterator>
struct iterator_traits
{
typedef typename _Iterator::iterator_category iterator_category;
typedef typename _Iterator::value_type value_type;
typedef typename _Iterator::difference_type difference_type;
typedef typename _Iterator::pointer pointer;
typedef typename _Iterator::reference reference;
}; // specialize for _Tp*
template <class _Tp>
struct iterator_traits<_Tp*>
{
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef _Tp& reference;
}; // specialize for const _Tp*
template <class _Tp>
struct iterator_traits<const _Tp*>
{
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef const _Tp* pointer;
typedef const _Tp& reference;
};
看了了么?这就是模板偏特化,与模板特化的区别在于,模板特化以后,实际上其本身已经不是templatized,而偏
特化,仍然带有templatized。也就是说不为空的<>,<>内部仍然指明是什么具体类型,我们来看一个实际的例子:
#include <iostream>
using namespace std; // 一般化设计
template <class T, class T1>
class TestClass
{
public:
TestClass()
{
cout<<"T, T1"<<endl;
}
}; // 针对普通指针的偏特化设计
template <class T, class T1>
class TestClass<T*, T1*>
{
public:
TestClass()
{
cout<<"T*, T1*"<<endl;
}
}; // 针对const指针的偏特化设计
template <class T, class T1>
class TestClass<const T*, T1*>
{
public:
TestClass()
{
cout<<"const T*, T1*"<<endl;
}
}; int main()
{
TestClass<int, char> obj;
TestClass<int *, char *> obj1;
TestClass<const int *, char *> obj2; return ;
}
特化与偏特化的调用顺序
对于模板、模板的特化和模板的偏特化都存在的情况下,编译器在编译阶段进行匹配时,是如何抉择的呢?从哲学的角度来说,应该先照顾最特殊的,然后才是次特殊的,最后才是最普通的。编译器进行抉择也是尊从的这个道理
oop &&GP 模板 ---> 特化和偏特化的更多相关文章
- C++模板编程里的主版本模板类、全特化、偏特化(C++ Type Traits)
1. 主版本模板类 首先我们来看一段初学者都能看懂,应用了模板的程序: 1 #include <iostream> 2 using namespace std; 3 4 template ...
- C++中模板的特化与偏特化
1.引言 C++中的模板分为类模板和函数模板,虽然它引进到C++标准中的时间不是很长,但是却得到了广泛的应用,这一点在STL中有着充分的体现.目前,STL在C++社区中得到了广泛的关注.应用和研究.理 ...
- [转]C++中模板的特化与偏特化
转载自:http://hi.baidu.com/klcdyx2008/blog/item/5adbf77b79f316f90bd1873c.html 1.引言C++中的模板分为类模板和函数模板,虽然它 ...
- 【校招面试 之 C/C++】第2题 函数模板、类模板、特化、偏特化
1.C++模板 说到C++模板特化与偏特化,就不得不简要的先说说C++中的模板.我们都知道,强类型的程序设计迫使我们为逻辑结构相同而具体数据类型不同的对象编写模式一致的代码,而无法抽取其中的共性,这样 ...
- C++ 模板的全特化与偏特化
模板为什么要特化,因为编译器认为,对于特定的类型,如果你能对某一功能更好的实现,那么就该听你的. 模板分为类模板与函数模板,特化分为全特化与偏特化.全特化就是限定死模板实现的具体类型,偏特化就是如果这 ...
- C++模板的特化与偏特化
http://cppblog.com/SmartPtr/archive/2007/07/04/27496.html (1) 类模板定义一个栈的类模板,它可以用来容纳不同的数据类型 template & ...
- C++模板特化与偏特化
C++模板 说到C++模板特化与偏特化,就不得不简要的先说说C++中的模板.我们都知道,强类型的程序设计迫使我们为逻辑结构相同而具体数据类型不同的对象编写模式一致的代码,而无法抽取其中的共性,这样显然 ...
- C++模板函数只能全特化不能偏特化
C++模板函数只能全特化不能偏特化
- C++模板显式实例化,隐式实例化,特化(具体化,偏特化)辨析
最近再次看C++ PRIMER PLUS的时候看到这个部分感觉讲得很烂,前后口径不一致,所以写个辨析让自己明白的同时也希望对此不太清楚的朋友能搞懂. 总结一下,C++只有模板显式实例化(explici ...
随机推荐
- win7 bat copy 一个文件 到另外的文件夹内,路径得用引号哦
win 7 的 用引号 把路径引起来 ,但是win10 的可以不用哦 !
- 【TOJ 3005】Triangle(判断点是否在三角形内+卡精度)
描述 Given the coordinates of the vertices of a triangle,And a point. You just need to judge whether t ...
- python 用selenuim判断页面是否全部加载完成,并且加上最大时长,超过时长报错
STR_READY_STATE = '' time_start = time.time() while STR_READY_STATE != 'complete': time.sleep(0.001) ...
- Ubuntu16.04采用FastCGI方式部署Flask web框架
1 部署nginx 1.1 安装nginx服务 root@desktop:~# apt-get install nginx -y 1.2 验证nginx服务是否启动 root@des ...
- 新知识 HtMl 5
快要毕业了,即将走向实习岗位,但是这日子过的太无聊了,昨天逃课回宿舍打开电脑想看电影但是没什么好看的,于是上床睡觉了,越躺越无聊,然后爬了起来到学习图书馆找了本HTML5的课本,学习了起来(我感觉ht ...
- 为什么我用了$().height()还是对不齐呢?
有一个这样的需求:有两个显示内容的框,要使他们高度一致,因为他们存放的内容多少和结构不一样,左边内容少,右边内容多.这就导致了右边会比左边高,解决方法就是超出部分用滚轮显示,那这时就先要调整右边的高度 ...
- ethereum(以太坊)(基础)--容易忽略的坑(二)
pragma solidity ^0.4.0; contract EMath{ string public _a="lin"; function f() public{ modif ...
- YII2.0 用GII创建视图文件后访问404
使用GII的CRUD Generator创建searchModelClass 和控制器类文件,视图文件后,访问控制器地址后出现404的情况. 创建过程如图所示 后来发现是控制器类 Controller ...
- 九、IIC驱动原理分析
学习目标:学习IIC驱动原理: 一.IIC总线协议 IIC串行总线包括一条数据线(SDA)和一条时钟线(SCL),支持“一主多从”和“多主机”模式:每个从机设备都有唯一的地址来识别. 图 1 IIC ...
- C语言实现简易扫雷
首先,写代码之前要将整体思路写出来: 扫雷游戏:1.需要两个二维数组,一个用来展示,一个用来放雷; 2.整体骨架在代码中都有注释说明; 3.游戏难度比较简单,适合初学者观看,如果有大佬看明白,可以指点 ...