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提供六大组件,彼此可以组合 ...
随机推荐
- Redis - (Linux)安装与配置
Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: 1:Redis支持数据的持久化,可以将内存 ...
- 一个非侵入的Go事务管理库——如何使用
在文章"清晰架构(Clean Architecture)的Go微服务: 事物管理"中,我谈到了如何在清晰架构中实现非侵入的事务管理. 它允许你把事务代码与业务逻辑代码分开,并且让你 ...
- 慕课网--docker走进第一个javaweb应用
zh docker镜像就是一系列文件的集合 docker 容器就是一个进程.将docker镜像运行起来就是一个docker容器 docker仓库就是存储docker镜像的 1.docker的安装 do ...
- Halcon斑点分析官方示例讲解
官方示例中有许多很好的例子可以帮助大家理解和学习Halcon,下面举几个经典的斑点分析例子讲解一下 Crystals 图中显示了在高层大气中采集到的晶体样本的图像.任务是分析对象以确定特定形状的频率. ...
- Flask-install-python2.6
命令: # 安装virtualenv $ sudo yum install python-setuptools $ sudo easy_install virtualenv OR sudo pip i ...
- 推荐一种通过刷leetcode来增强技术功底的方法
背景 如果前人认为这个一种学习提高或者检验能力的成功实践.而自己目前又没有更好的方法,那就不妨试一试. 而不管作为面试官还是被面试者,编码题最近越来越流行.而两种角色都需要思考的问题是希望考察什么能力 ...
- 前端基础:”天龙八步“细说浏览器输入URL后发生了什么
参考:https://www.xuecaijie.com/it/157.html#1Q64p5DeC8dKFF 本文摘要: 1.DNS域名解析: 2.建立TCP连接: 3.发送HTTP请求: 4.服务 ...
- 一.8.django权限管理/drf权限管理
1.什么是权限管理: .权限管理,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源 .权限管理好比如钥匙,有了钥匙就能把门打开,但是权限设置是有级别之分的,假如这个系 ...
- centos7在Evolution中配置163邮箱,被阻止收件解决方法
config.mail.163.com/settings/imap/login.jsp?uid=xxxx@163.com
- 探讨NET Core数据进行3DES加密或解密弱密钥问题
前言 之前写过一篇<探讨.NET Core数据进行3DES加密和解密问题>,最近看到有人提出弱密钥问题,换个强密钥不就完了吗,猜测可能是与第三方对接导致很无奈不能更换密钥,所以产生本文解决 ...