STL源码剖析:配接器
启
配接器就是适配器
STL中的适配器一共三种:
迭代器适配器
是一种观念上的改变,如将赋值操作变成插入,前进变成后退,等
函数适配器
STL中最广泛的配接器群体
可以实现连续配接
配接操作:bind,negate,compose
容器适配器
stack和queue的底层都是deque
Iterator adapter
iterator adapter中也维护一个容器,iterator adapter就是开放内部维护的容器的一些方法和关闭一些方法
back_insert_iterator:将赋值操作变成尾插
template <class Container>
class back_insert_iterator
{
protected:
Container* container; public:
explict back_insert_iterator(Container& x) : container(&x) {} // 主要提供的方法
back_insert_iterator<Container>& operator=(const typename Container::value_type& value)
{
container->push_back(value);
return *this;
} // 关闭下列方法
back_insert_iterator<Container>& operator*() { return *this; }
back_insert_iterator<Container>& operator++() { return *this; }
back_insert_iterator<Container>& operator++(int) { return *this; }
} template <class Container>
inline back_insert_iterator<Container> back_inserter(Container& x)
{
return back_insert_iterator<Container>(x);
}
- front_insert_iterator:将赋值操作变成头插
template <class Container>
class front_insert_iterator
{
protected:
Container* container; public:
explict front_insert_iterator(Container& x) : container(&x) {} // 主要提供的方法
front_insert_iterator<Container>& operator=(const typename Container::value_type& value)
{
container->push_front(value);
return *this;
} // 关闭下列方法
front_insert_iterator<Container>& operator*() { return *this; }
front_insert_iterator<Container>& operator++() { return *this; }
front_insert_iterator<Container>& operator++(int) { return *this; }
} template <class Container>
inline front_insert_iterator<Container> front_inserter(Container& x)
{
return front_insert_iterator<Container>(x);
}
- insert_iterator:将赋值操作变成在指定位置后插入,便于连续赋值
template <class Container>
class insert_iterator
{
protected:
Container* container;
typename Container::iterator iter; public:
explictinsert_iterator(Container& x, typename Container::iterator i) : container(&x), iter(i) {} // 主要提供的方法
insert_iterator<Container>& operator=(const typename Container::value_type& value)
{
container->insert(iter, value);
++iter;
return *this;
} // 关闭下列方法
insert_iterator<Container>& operator*() { return *this; }
insert_iterator<Container>& operator++() { return *this; }
insert_iterator<Container>& operator++(int) { return *this; }
} template <class Container, class Iterator>
inline insert_iterator<Container> front_inserter(Container& x, Iterator i)
{
typedef typename Container::iterator iter;
return insert_iterator<Container>(x, iter(i));
}
- reverse_iterator:将某个迭代器反向移动
template <class Iterator>
class reverse_iterator
{
protected:
Iterator current; public:
typedef Iterator iterator_type; // 正向迭代器
typedef reverse_iterator<Iterator> self; // 反向迭代器 reverse_iterator() {}
explicit reverse_iterator(iterator_type x) : current(x) {}
explicit reverse_iterator(const self& x) : current(x.current) {} iterator_type base() const { return currrent; } reference operator*() const
{
Iterator tmp = current;
return *--tmp;
} reference operator->() const
{
return &(operator*());
} self& operator++()
{
--current;
return *this;
} self& operator++(int)
{
self tmp = current;
--current;
return tmp;
} self& operator--()
{
++current;
return *this;
} self& operator--(int)
{
self tmp = current;
++current;
return tmp;
} self operato+(difference_type n) const
{
return self(current - n);
} self& operato+=(difference_type n)
{
current -= n;
return self;
} self operato-(difference_type n) const
{
return self(current + n);
} self& operato-=(difference_type n)
{
current += n;
return self;
} reference operator[](difference_type n) const
{
return *(*this + n)
}
}
- istream_iterator:绑定到istream上,拥有输入能力
template <class T, class Distance = ptrdiff_t>
class istream_iterator
{
protected:
istream* stream;
T value;
bool end_mark;
void read()
{
end_mark = (*stream) ? true :false;
if(end_mark)
{
*stream >> value;
}
end_mark = (*stream) ? true :false;
} public:
istream_iterator() : stream(&cin), end_mark(false) {}
istream_iterator(istream& s) : stream(&s), end_mark(false) { read(); } reference operator*() const { return value; }
reference operator->() const { return &(operator*()); } istream_iterator<T, Distance>& operator++()
{
read();
return *this;
} istream_iterator<T, Distance>& operator++(int)
{
istream_iterator<T, Distance> tmp = *this;
read();
return tmp;
}
}
- ostream_iterator:绑定到ostream上,拥有输出能力
template <class T>
class ostream_iterator
{
protected:
ostream* stream;
const char* string; // 每次输出后的间隔符 public:
ostream_iterator(ostream& s) :stream(&s), string() {}
ostream_iterator(ostream& s, const char* c): stream(&s), string(c) {} ostream_iterator<T>& operator=(const T& value)
{
*stream << value;
if(string)
{
*stream << string;
}
return *this;
} ostream_iterator<T>& operator*() { return *this; }
ostream_iterator<T>& operator++() { return *this; }
ostream_iterator<T>& operator++(int) { return *this; }
}
Function adapter
就是使用组合的方式,组合多个仿函数
对返回值进行逻辑取反:not1、not2
// 配接的仿函数接收两个参数
template <class Predicate>
class binary_negate : public binary_function<typename Predicate::first_argument_type, typename Predicate::second_argument_type, bool>
{
Predicate pre;
public:
explicate binary_negate(const Predicate& x) :prd(x) {} bool operator()(const typename Predicate::argument_type& x, typename Predicate::second_argument_type& y) const
{
return !(ped(x, y));
}
} template <class Predicate>
inline binary_negate<Predicate> not2(const Predicate& pred)
{
return binary_negate<Predicate>(pred);
}
- 对参数进行绑定:bind1st、bind2nd
就是指定仿函数中的参数中的某一个为固定值
template <class Operator>
class binder1st : public unary_function<typename Operator::second_argument_type, typename Operator::result_type>
{
Operator op;
typename Operator::first_argument_type value; public:
bind1st(const Operator& x, const typename Operator::first_argument_type* y) : op(x), value(y) {} typename Operator::result_type operator()(typename Operator::second_argument_type& x) const
{
return op(value, x);
}
} template <class Operator, class T>
inline binder1st<Operator> bind1st(const Operator& op, const T& x)
{
typedef typename Operator::first_argument_type arg1_type;
return binder1st<Operator>(op, arg1_type(x));
}
template <class Operator>
class binder2nd : public unary_function<typename Operator::first_argument_type, typename Operator::result_type>
{
Operator op;
typename Operator::second_argument_type value; public:
bind1st(const Operator& x, const typename Operator::second_argument_type* y) : op(x), value(y) {} typename Operator::result_type operator()(typename Operator::first_argument_type& x) const
{
return op(x, value);
}
} template <class Operator, class T>
inline binder2nd<Operator> bind1st(const Operator& op, const T& x)
{
typedef typename Operator::second_argument_type arg2_type;
return binder1st<Operator>(op, arg2_type(x));
}
- 对函数进行合成:compose1、compose2
// h(x) = f(g(x))
template <class Operation1, class Operation2>
class unary_compose : public unary_function<typename Operation2::argument_type,
typename Operation1::result_type>
{
Operation1 op1;
Operation2 op2;
public:
unary_compose(const Operation1& x, const Operation2& y) : op1(x), op2(y) {} typename Operation1::result_type operator()(typename Operation2::argument_type& x) const
{
return op1(op2(x));
}
} template <class Operation1, class Operation2>
inline unary_compose<Operation1, Operation2>compose1(const Operation1& x, const Operation2& y)
{
return unary_compose<Operation1, Operation2>(op1, op2);
}
// h(x) = f(g1(x), g2(x))
template <class Operation1, class Operation2, class Operation3>
class binay_compose : public unary_function<typename Operation2::argument_type,
typename Operation1::result_type>
{
Operation1 op1;
Operation2 op2;
Operation3 op3; public:
binay_compose(const Operation1& x, const Operation2& y, cosnt Operation3& z) : op1(x), op2(y), op3(z) {} typename Operation1::result_type operator()(typename Operation2::argument_type& x) const
{
return op1(op2(x), op3(x));
}
} template <class Operation1, class Operation2, class Operation3>
inline binay_compose<Operation1, Operation2, Operation3> compose2(const Operation1& x, const Operation2& y, cosnt Operation3& z)
{
return binay_compose<Operation1, Operation2, Operation3>(op1, op2, op3);
}
- 用于函数的指针:包装一般函数,使得一般函数也可以适用于Function adapter中
// 包装的函数只有一个参数
template <class Arg, class Result>
class pointer_to_unary_function : public unary_function<Arg, Result>
{
Result (*ptr)(Arg); public: explict pointer_to_unary_function(Result (*x)(Arg)) : ptr(x) {} Result operator()(Arg x) const
{
return ptr(x);
}
} template <class Arg, class Result>
inline pointer_to_unary_function<Arg, Result>ptr_fun(Result (*ptr)(Arg))
{
return pointer_to_unary_function<Arg, Result>(x);
}
// 包装的函数有两个参数
template <class Arg1, class Arg2, class Result>
class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result>
{
Result (*ptr)(Arg1, Arg2); public: explict pointer_to_unary_function(Result (*x)(Arg1, Arg2)) : ptr(x) {} Result operator()(Arg1 x, Arg2 y) const
{
return ptr(x, y);
}
} template <class Arg1, class Arg2, class Result>
inline pointer_to_unary_function<Arg1, Arg2, Result>ptr_fun(Result (*ptr)(Arg1 x, Arg2 y))
{
return pointer_to_unary_function<Arg1, Arg2, Result>(x, y);
}
- 用于成员函数的指针:mem_fun、mem_fun_ref
mem_fun、mem_fun_ref修饰的成员函数不具备多态性质
// 无参数成员函数调用,其他有参数函数的调用方式类似
template <class S, class T>
class mem_fun_t : public unary_function<T*, S>
{
S (T::*f)();
public:
explict mem_fun_t(S (T::*pf)()) : f(pf) {} S operator()(T* p) const
{
return (p->*f)();
}
} template <class S, class T>
inline mem_fun_t<S, T> mem_fun(S (T::*f)())
{
return mem_fun_t<S, T>(f);
}
STL源码剖析:配接器的更多相关文章
- STL源码剖析 — 空间配置器(allocator)
前言 以STL的实现角度而言,第一个需要介绍的就是空间配置器,因为整个STL的操作对象都存放在容器之中. 你完全可以实现一个直接向硬件存取空间的allocator. 下面介绍的是SGI STL提供的配 ...
- STL源码剖析——空间配置器Allocator#2 一/二级空间配置器
上节学习了内存配置后的对象构造行为和内存释放前的对象析构行为,在这一节来学习内存的配置与释放. C++的内存配置基本操作是::operator new(),而释放基本操作是::operator del ...
- STL源码剖析:配置器
作用:对内存的管理 接口:申请和释放 内容: 几个全局函数 一级配置器 二级配置器 准备知识 POD是什么: Plain Old Data简称POD,表示传统的C语言类型:与POD类型对应的是非POD ...
- STL源码剖析(空间配置器)
前言 在STL中,容器的定义中都带一个模板参数,如vector template <class T, class Alloc = alloc> class vector {...} 其中第 ...
- STL源码剖析——空间配置器Allocator#3 自由链表与内存池
上节在学习第二级配置器时了解了第二级配置器通过内存池与自由链表来处理小区块内存的申请.但只是对其概念进行点到为止的认识,并未深入探究.这节就来学习一下自由链表的填充和内存池的内存分配机制. refil ...
- STL源码剖析——空间配置器Allocator#1 构造与析构
以STL的运用角度而言,空间配置器是最不需要介绍的东西,因为它扮演的是幕后的角色,隐藏在一切容器的背后默默工作.但以STL的实现角度而言,最应该首先介绍的就是空间配置器,因为这是这是容器展开一切运作的 ...
- 《STL源码剖析》相关面试题总结
原文链接:http://www.cnblogs.com/raichen/p/5817158.html 一.STL简介 STL提供六大组件,彼此可以组合套用: 容器容器就是各种数据结构,我就不多说,看看 ...
- 面试题总结(三)、《STL源码剖析》相关面试题总结
声明:本文主要探讨与STL实现相关的面试题,主要参考侯捷的<STL源码剖析>,每一个知识点讨论力求简洁,便于记忆,但讨论深度有限,如要深入研究可点击参考链接,希望对正在找工作的同学有点帮助 ...
- STL源码剖析之空间配置器
本文大致对STL中的空间配置器进行一个简单的讲解,由于只是一篇博客类型的文章,无法将源码表现到面面俱到,所以真正感兴趣的码农们可以从源码中或者<STL源码剖析>仔细了解一下. 1,为什么S ...
- STL"源码"剖析-重点知识总结
STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...
随机推荐
- 阿里巴巴--mysql中Mysql模糊查询like效率,以及更高效的写法
在使用msyql进行模糊查询的时候,很自然的会用到like语句,通常情况下,在数据量小的时候,不容易看出查询的效率,但在数据量达到百万级,千万级的时候,查询的效率就很容易显现出来.这个时候查询的效率就 ...
- Python3-hashlib模块-加密算法之安全哈希
Python3中的hashlib模块提供了多个不同的安全哈希算法的通用接口 hashlib模块代替了Python2中的md5和sham模块,使用这个模块一般分为3步 1.创建一个哈希对象,使用哈希算法 ...
- (数据科学学习手札88)基于geopandas的空间数据分析——空间计算篇(下)
本文示例代码及数据已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 在基于geopandas的空间数据分析系列 ...
- SQL注入入门
这几天做了不少SQL注入题,对SQL注入有点体会,所以写写自己的学习历程与体会. 什么是SQL注入 SQL注入就是指web程序对用户输入的数据的合法性没有进行判断,由前端传入的参数带着攻击者控制的非法 ...
- 入门大数据---Hive数据查询详解
一.数据准备 为了演示查询操作,这里需要预先创建三张表,并加载测试数据. 数据文件 emp.txt 和 dept.txt 可以从本仓库的resources 目录下载. 1.1 员工表 -- 建表语句 ...
- 进度条的使用 Progress控件
MFC编程实例二:进度条的使用 2011-03-22 09:09:09| 分类: C++(C语言) | 标签:进度 nlower nupper 添加 mfc |字号 订阅 本人用的 ...
- 不就是语法和长难句吗—笔记总结Day4
第六课 英语的特殊结构 1.强调句型 It is...that / who / which(少见)... * 强调句型可以强调句子中所有成分(唯一不能强调谓语)* It is obviously t ...
- 宿主机ping不通虚拟机,虚拟机能ping通宿主机问题
打开虚拟机管理器,点开设置=>网络,网络选的是NAT,所以宿主机不能直接ping能虚拟机!!! 问题描述 查看虚拟机ip, #ifconfig如下图: 宿主机ping虚拟机ip,无法通信,如下 ...
- 组合 a 标签与 canvas 实现图片资源的安全下载的方法与技巧
普通用户下载图片时只需一个「右键另存为」操作即可完成,但当我们做在线编辑器.整个 UI 都被自定义实现时,如何解决不同域问题并实现页面中图片资源的安全下载呢?本文就解决该问题过程中所涉及的正则表达式. ...
- Codeforces 1292C Xenon's Attack on the Gangs 题解
题目 On another floor of the A.R.C. Markland-N, the young man Simon "Xenon" Jackson, takes a ...