《深入实践C++模板编程》之五——容器与迭代器
template<typename T> class list; template<typename T>
struct list_node
{
typedef T value_type;
typedef T& reference_type;
typedef const T const_reference_type; T value;
list_node *prev;
list_node *next; list_node(T const &value, list_node *prev, list_node *next) :
value(value), prev(prev), next(next){}
}; template<typename N>
class list_iterator
{
N *pos;
template<typename T> friend class list; public:
typedef typename N::value_type value_type;
typedef typename N::reference_type reference_type;
typedef typename N::const_reference_type const_reference_type;
typedef list_iterator<N> self_type; list_iterator() :pos(){}
list_iterator(N *pos) :pos(pos){} bool operator != (self_type const &right) const{
return pos != right.pos;
} bool operator == (self_type const &right) const{
return pos != right.pos;
} self_type& operator++(){
if (pos) pos = pos->next;
return *this;
} reference_type operator * () throw (std::runtime_error){
if (pos) return pos->value;
else throw (std::runtime_error("null iterator!\n"));
}
}; template<typename T>
class list
{
typedef list_node<T> node_type;
node_type *head; public:
typedef T value_type;
typedef list_iterator<node_type> iterator; list() :head(){}
~list(){
while (head)
{
node_type *n = head;
head = head->next;
delete n;
}
} void push_front(T const &v)
{
head = new node_type(v, , head);
if (head->next)
{
head->next->prev = head;
}
} void pop_front(T const &v)
{
if (head)
{
node_type *n = head;
head = head->next;
head->prev = ;
delete n;
}
} void insert(iterator it, T const &v)
{
node_type *n = it.pos;
if (n)
{
node_type *new_node = new node_type(v, n, n->next);
new_node->next->prev = new_node;
n->next = new_node;
}
} void erase(iterator &it)
{
node_type *n = it.pos;
++it;
if (n)
{
if (n->next)
{
n->next->prev = n->prev;
}
if (n->prev)
{
n->prev->next = n->next;
}
if (head == n)
{
head = n->next;
}
delete n;
}
} bool is_empty() const { return head == ; }
iterator begin(){ return iterator(head); }
iterator end(){ return iterator(); }
};
template<typename T>
struct tree_node
{
typedef T value_type;
typedef T& reference_type;
typedef const T& const_reference_type; T value;
tree_node *parent;
tree_node *left;
tree_node *right; tree_node(T const &value,
tree_node *parent,
tree_node *left,
tree_node *right):
value(value),
parent(parent),
left(left),
right(right){} ~tree_node()
{
if (left) delete left;
if (right) delete right;
}
}; template<typename N>
class tree_iterator
{
const N *pos;
public:
typedef typename N::value_type value_type;
typedef typename N::const_reference_type const_reference_type;
typedef tree_iterator<N> self_type; tree_iterator() :pos(){}
tree_iterator(const N *pos) :pos(pos){} bool operator == (self_type const &right) const{
return pos == right.pos;
} self_type& operator ++ (){
if (pos){
if (pos->right){
pos = pos->right;
while (pos->left)
{
pos = pos->left;
}
}
else
{
while (pos->parent && (pos->parent->right == pos))
{
pos = pos->parent;
}
pos = pos->parent;
}
}
return *this;
} const_reference_type operator * () const throw(std::runtime_error)
{
if (pos)
{
return pos->value;
}
else
{
throw std::runtime_error("Null iterator!\n");
}
}
}; template<typename T>
class set
{
typedef tree_node<T> node_type;
node_type *root;
public:
typedef T value_type;
typedef tree_iterator<node_type> const_iterator; set() :root(){}
~set(){ if (root) delete root; } bool insert(T const &v)
{
node_type **n = &root;
node_type *p = ;
while (*n)
{
if (v == (*n)->value)
{
return false;
}
else
{
p = *n;
n = v < (*n)->value ? &((*n)->left) : &((*n)->right);
}
}
*n = new node_type(v, p, , );
return true;
} bool has(T const &v)
{
node_type *n = root;
while (n)
{
if (v == n->value)
return true;
n = v < n->value ? n->left : n->right;
}
return false;
} bool is_empty() const { return root == ; } const_iterator begin() const{
node_type *n = root;
while (n->left) n = n->left;
return const_iterator(n);
} const_iterator end() const { return const_iterator(); }
};
template<typename C>
typename C::value_type
sum(C &c)
{
typedef typename C::value_type value_type;
typedef typename C::iterator iterator;
value_type sum(); for (iterator i = c.begin(); i != c.end(); ++i)
{
sum += *i;
}
return sum;
}
template<typename I>
typename I::value_type
sum(I begin, I end)
{
typedef typename I::value_type value_type; value_type sum();
for (; begin != end; ++begin)
{
sum += *begin;
}
return sum;
}
template<typename I>
struct iterator_traits
{
typedef typename I::value_type value_type;
}; template<typename P>
struct iterator_traits<P*>
{
typedef P value_type;
};
template<typename I>
typename iterator_traits<I>::value_type
sum(I begin, I end)
{
typedef typename iterator_traits<I>::value_type value_type; value_type sum();
for (; begin != end; ++begin)
{
sum += *begin;
}
return sum;
}
《深入实践C++模板编程》之五——容器与迭代器的更多相关文章
- 《深入实践C++模板编程》之六——标准库中的容器
1.容器的基本要求 a.并非所有的数据都可以放进容器当中.各种容器模板对所存数据类型都有一个基本要求——可复制构造.将数据放进容器的过程就是通过数据的复制构造函数在容器内创建数据的一个副本的过程. b ...
- 《深入实践C++模板编程》之四——特例
1. 所谓模板特例,是针对符合某种条件的模板参数值集合另外声明的模板实现变体. template<typename T> class my_vector; template<> ...
- 《深入实践C++模板编程》之三——模板参数类型详解
非类型模板参数 和 模板型模板参数 整数以及枚举类型:指向对象或者函数的指针:对对象或函数的引用:指向对象成员的指针.统称为非类型模板参数. 模板型模板参数,是指模板参数还可以是一个模板. 1.整 ...
- 《深入实践C++模板编程》之二——模板类
1.类的模板的使用 类,由于没有参数,所以没有模板实参推导机制. #include <stdexcept> template<typename T> class my_stac ...
- 《深入实践C++模板编程》之一——Hello模板
1.通过一个简单的例子来理解模板的用途: 模板为不同类型的数据生成操作相同或相似的函数. 弱语言如Python,可以使用一种函数来应对各种类型,但是C++就不得不为不同的类型编写相似的函数.模板的作用 ...
- c++ 模板参数做容器参数迭代器报错 vector<T>::const_iterator,typename const报错
错误1: template<class T>void temp(std::vector<T>& container){ std::vector<T& ...
- STL(标准模板库)理论基础,容器,迭代器,算法
基本概念 STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.现然主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段时间. ...
- C++之模板编程
当我们越来越多的使用C++的特性, 将越来越多的问题和事物抽象成对象时, 我们不难发现:很多对象都具有共性. 比如 数值可以增加.减少:字符串也可以增加减少. 它们的动作是相似的, 只是对象的类型不同 ...
- c++ 基于Policy 的 模板编程
在没真正接触c++ 模板编程之前.真的没有想到c++ 还能够这么用.最大的感触是:太灵活了,太强大了. 最初接触模板威力还是在Delta3d中,感觉里面的模板使用实在是灵活与方便,特别是dtAI中使 ...
随机推荐
- 2个最好的JavaScript编辑器 必须要知道
JavaScript程序员有许多很好的工具可供选择,几乎太多了.在这篇文章中,介绍2个最好用的文本编辑器,也是顶级的.并且很好地支持使用JavaScript,HTML5和CSS进行开发,并用Markd ...
- 演示Java如何调用Mysql的过程和函数
这里只演示Java如何调用Mysql的过程和函数 --------------------------------------------------------------------------- ...
- 9Patch图
NinePatch是一种很有用的PNG图片格式,它可以在特定区域随文字大小进行缩放. - 上边线控制水平拉伸- 左边线控制竖直拉伸- 右边线和下边线控制内容区域 如下: 背景图片的中间区域会随着文字的 ...
- NginxURL重新配置
server { listen 8080; server_name localhost; rewrite /ljys/kcf(.*) http://192.168.4.139:8080/wuxi-pr ...
- Linux命令jobs小记
命令使用过程中,输出中总是会带两个符号:+ 和 -,如: [1] 7893 Running gpass & [2] 7904 Running gnome-calculator & [3 ...
- 小D课堂 - 新版本微服务springcloud+Docker教程_6-05 高级篇幅之高并发情况下
笔记 5.高级篇幅之高并发情况下接口限流特技 简介:谷歌guava框架介绍,网关限流使用 1.nginx层限流 2.网关层限流 开始 mysql最大的连接数就是3千多.如果想把应用搞好 ...
- spark简单快速学习及打开UI界面---1
1.远程集群测试 import org.apache.spark.{SparkContext, SparkConf} import scala.math.random /** * 利用spark进行圆 ...
- linux定时脚本:删除linux/HDFS上过期文件
一.定时删除linux上定时的文件 显示20分钟前的文件 -exec ls -l {} \; 删除20分钟前的文件 -exec rm {} \; 显示20天前的文件 -exec ls -l {} \; ...
- DISCUZ论坛各大功能模块入口文件介绍
index.php 首页入口文件,这个文件相信大家都不陌生,小编就不具体介绍了. forum.php 论坛入口文件 portal.php 门户入口文件 group.php 群组入口文件 home.ph ...
- 【JVM学习笔记】线程上下文类加载器
有许多地方能够看到线程上下文类加载的设置,比如在sun.misc.Launcher类的构造方法中,能够看到如下代码 先写一个例子建立感性认识 public class Test { public st ...