《深入实践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中使 ...
随机推荐
- vue 无法覆盖vant的UI组件的样式
vue 无法覆盖vant的UI组件的样式 有时候UI组件提供的默认的样式不能满足项目的需要,就需要我们对它的样式进行修改,但是发现加了scoped后修改的样式不起作用. 解决方法: 使用深度选择器,将 ...
- Flutter移动电商实战 --(12)首页导航区域编写
1.导航单元素的编写 从外部看,导航是一个GridView部件,但是每一个导航又是一个上下关系的Column.小伙伴们都知道Flutter有多层嵌套的问题,如果我们都写在一个组件里,那势必造成嵌套严重 ...
- P3146 [USACO16OPEN]248
P3146 [USACO16OPEN]248 题解 第一道自己码出的区间DP快庆祝一哈 2048 每次可以合并任意相邻的两个数字,得到的不是翻倍而是+1 dp[L][R] 区间 L~R 合并结果 然后 ...
- leetcode16 最接近的三数之和
做了几周的hard之后,这道题居然轻易就解出来了,稍微debug了一下就ac了,算是有了一丢丢提高把: 思路 这道题因为和三数之和很像,所以充分利用双指针的思想:先排序,然后再固定一个数i,i取值从[ ...
- python之scrapy初探
1.知识点 """ Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量的代码,就能够快速的抓取 Scrapy模块: 1.schedul ...
- [CDH] Cloudera's Distribution including Apache Hadoop
You may choose to install spark, yarn, hive, etc one by one. [Spark] 00 - Install Hadoop & Spark ...
- iOS模型输出和打印
在调试时,我们经常用到输出model,查看数据是否正确,还会在控制台"po 模型"操作,一般输出都是这样的格式的: person is <Person: 0x60800003 ...
- SpringBoot: 9.整合thymeleaf(转)
1.创建maven项目,添加项目所需依赖 <!--springboot项目依赖的父项目--> <parent> <groupId>org.springframewo ...
- 前端学习之JavaScript(1)
目录 一. JavaScript简介 二. 第一个JavaScript代码 三. 基本数据类型 四. 运算符 五. 数据类型转换 六. 流程控制 七. 常用内置对象 八. 函数 一. JavaScri ...
- 【Web】如何注释?
HTML 形式:<!-- 注释内容 --> 实例: <!-- <p>这是第一段</p> --> CSS 形式:/* 注释内容 */ 实例: /* 选中i ...