STL迭代器之一:偏特化
在stl的算法中运用容器的迭代器时,很可能经常会用到迭代器相应型别(例如迭代器所指物的型别),假设算法中有必要声明一个变量,以“迭代器所指对象的型别”为类型,如何是好,例如我们写一个功能,打印迭代器元素的值:
template <class T>
struct MyIter
{
typedef T value_type;
T* ptr;
MyIter(T* p = NULL):ptr(p){}
T& operator*()const {return *ptr;}
}; template <class T>
typename T::value_type func(T iter)
{
return *iter;
} int main()
{
MyIter<int> ite(new int());
printf("%d", func(ite));
return ;
}
但是我们无法支持原生指针,比如
int a = 10;
int b = func(&a);
这里偏特化可以帮我们实现,"所谓partial specialization"的意思就是提供另一份template的定义式,而其本身仍为templatized”。
“针对(任何)template 参数更进一步的条件限制所设计出来的一个特化版本”——《泛型思维》
第一步定义iterator_traits中间层:
template <class T>
struct MyIter
{
typedef T value_type;
T* ptr;
MyIter(T* p = NULL):ptr(p){}
T& operator*()const {return *ptr;}
}; //针对带内嵌类型的迭代器
template <class I>
struct iterator_traits
{
typedef typename I::value_type value_type;
}; template <class T>
typename iterator_traits<T>::value_type func(T iter)
{
return *iter;
} int main()
{
MyIter<int> ite(new int());
printf("%d", func(ite)); return ;
}
输出:8
第二步,针对原生指针设计一个特化版本:
template <class T>
struct MyIter
{
typedef T value_type;
T* ptr;
MyIter(T* p = NULL):ptr(p){}
T& operator*()const {return *ptr;}
}; //针对带内嵌类型的迭代器
template <class I>
struct iterator_traits
{
typedef typename I::value_type value_type;
}; //针对原生指针
template <class I>
struct iterator_traits<I*>
{
typedef I value_type;
}; template <class T>
typename iterator_traits<T>::value_type func(T iter)
{
return *iter;
} int main()
{
MyIter<int> ite(new int());
printf("%d\n", func(ite));
int a = 1;
printf("%d\n", func(&a));
return ;
}
但是假设我在func里面希望做如下操作:
template <class T>
typename iterator_traits<T>::value_type func(T iter)
{
typename iterator_traits<T>::value_type a;
a++; //这里将报错,const 常量无法修改
return *iter;
}
我们希望的效果是:只想定义一个T类型的数据类型,如果需要const修饰,我们自己在类型前面加个const即可。
于是我们还要对const T*设计一个特化版本:
template <class T>
struct MyIter
{
typedef T value_type;
T* ptr;
MyIter(T* p = NULL):ptr(p){}
T& operator*()const {return *ptr;}
}; //针对带内嵌类型的迭代器
template <class I>
struct iterator_traits
{
typedef typename I::value_type value_type;
}; //针对原生指针
template <class I>
struct iterator_traits<I*>
{
typedef I value_type;
};
//针对const原生指针
template <class I>
struct iterator_traits<const I*>
{
typedef I value_type;
}; template <class T>
typename iterator_traits<T>::value_type func(T iter)
{
typename iterator_traits<T>::value_type a;
a++;
return *iter;
} int main()
{
MyIter<int> ite(new int());
printf("%d\n", func(ite));
int a = ;
const int* pa = &a;
func(pa); return ;
}
STL迭代器之一:偏特化的更多相关文章
- C++的模板特化 和 STL中iterator_traits模板的偏特化
C++中有类模板和函数模板,它们的定义如下所示: 类模板: template<class T1,class T2> class C { //... }; 函数模板: template< ...
- [C++ 2011 STL (VS2012 Update4) 源代码阅读系列(2)]熟悉一些宏定义和模版偏特化或叫模版专门化
[C++ 2011 STL (VS2012 Update4) 源代码阅读系列(2)]熟悉一些宏定义和模版偏特化或叫模版专门化 // point_test.cpp : 知识点练习和测试,用于单步调试,跟 ...
- STL 全特化/偏特化
template<class T> class Compare { public: static bool isEqual(const T& lh,const T& rh) ...
- STL全特化与偏特化
在泛型编程中,常常会使用一些非完全泛型的类模板,这就是特化. 如何理解全特化呢?如上图所示,第一个template class是空间配置器的类模板,第二个就是一个全特化的template class. ...
- stl迭代器原理
具体实现肯定不如书上讲的清楚了,这里只是根据侯捷书上的讲解,自己建立一条思路以及形成一些相关的概念 迭代器也可被称作智能指针,用于遍历容器内的元素,stl每个容器都实现了自己的iterator,ite ...
- [转]Traits 编程技法+模板偏特化+template参数推导+内嵌型别编程技巧
STL中,traits编程技法得到了很大的应用,了解这个,才能一窥STL奥妙所在. 先将自己所理解的记录如下: Traits技术可以用来获得一个 类型 的相关信息的. 首先假如有以下一个泛型的迭代器类 ...
- 一步一步的理解C++STL迭代器
一步一步的理解C++STL迭代器 "指针"对全部C/C++的程序猿来说,一点都不陌生. 在接触到C语言中的malloc函数和C++中的new函数后.我们也知道这两个函数返回的都是一 ...
- STL——迭代器与traits编程技法
一.迭代器 1. 迭代器设计思维——STL关键所在 在<Design Patterns>一书中对iterator模式定义如下:提供一种方法,使之能够依序巡访某个聚合物(容器)所含的各个元素 ...
- oop &&GP 模板 ---> 特化和偏特化
OOP面向对象编程 GP泛型编程(generic programming) 两者的主要区别就是OOP将数据和对数据的操作放在一起, GP就是将数据和操作独立开来 GP: 数据就是container ...
随机推荐
- chrome/ie中图片底部多出几像素问题
如果给图片的父元素设置背景色,则图片的底部就会多出几像素,chrome/IE/FF中均是如此,如下图: 代码如下,就是简单的div中放张图片: <!doctype html> <ht ...
- JavaScript 常用小功能
判断一个是否是隐藏状态 $(curid).is(":visible") 响应回车 $("#password").keydown(function (e) { ...
- ubuntu下sublime中文无法输入的问题
感谢- http://www.cnblogs.com/ningvsban/p/4346766.html
- Ajax 提交session实效跳转到完整的登陆页面
在spring security 中 Ajax提交时,session超时,局部加载登陆页面,为解决这个问题,重写ajax提交,返回的是modeview或者没有制定datatype时; 如果检测到加载到 ...
- nodejs单元测试
前言: 之前一直听说过单元测试,但是具体怎么做,也没有深入研究,感觉测试是一件很麻烦的事,花费时间.可能是自己太懒了,一看到测试那么多陌生的东西就不想弄了. 然后一拖再拖,直到最近,换了一家公司,然后 ...
- 强势回归,Linux blk用实力证明自己并不弱!
Flash的出现把存储的世界搅翻了天,仿佛一夜之间发现了新大陆,所有旧世界的东西都变得笨拙.NVMe驱动义无反顾地抛弃了Linux blk,开发自己的队列管理. 当第一次看到NVMe重新使用Linux ...
- 基于WebDriverAgent代理服务,实现iOS手机app自动化测试的框架搭建
iOS自动化测试一直使用的appium,iOS系统升级至10.0 Xcode8.0之后, 改用WebDriverAgent代理服务作为server,编写了一套基于WebDriverAgent服务 ap ...
- (AIDE)Android Eclipse JNI 调用 .so文件加载问题
背景:对于Android工程 Eclipse里编译好的.so文件放到 libs\armeabi下以后, 这样.so文件就可以打包到apk文件里,在apk装到手机上以后 在libs\armeabi下的. ...
- PHP购物车类
<?php /** * 购物车类 */ session_start(); class Cart{ private static $ins = null; private $items = arr ...
- C语言函数指针实验
上次看Atmel的示例工程,发现人家使用了函数指针的结构体(函数指针结构体).感叹人家的C语言功夫审核,自己费劲还是只能读懂的份.不过,函数指针确实好用.今天就试试这个超牛的东西.Now let's ...