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提供六大组件,彼此可以组合 ...
随机推荐
- matplotlib 强化学习
matplotlib 强化学习 import matplotlib.pyplot as plt ...
项目组要用到robot framework验收web,因此花了两天时间了解了一下这个框架.我把网上各位大侠分享的内容整理成一个小小demo,参考的出处没有列出来,在此一并感谢各位. demo仍旧是打开 ...
- 《UNIX环境高级编程》(APUE) 笔记第七章 - 进程环境
7 - 进程环境 Github 地址 1. main 函数 C 程序总是从 main 函数 开始执行: int main(int argc, char *argv[]); \(argc\) 为命令行参 ...
- C++版的网络数据包解析策略(升级版)
初版:http://www.cnblogs.com/wjshan0808/p/6580638.html 说明:在实现了对应的接口后该策略可以适合绝大多数的网络数据包结构 首先,是三个接口 IProdu ...
- 一周学会linux实战笔记
山篇 思考------实践-------再思考-------再实践 1.高效愉快地学习 2.先建立一个整体框架,然后细节 3.用的什么再学习什么 4.先know how,再know why 5.计算机 ...
- css中 出现height为100%失效的原因及解决方案
我们都知道需要给html和body标签设置了高度height:100%之后,再给内部的div设置height:100%的时候,内部div的高度100%才会起到作用.这是由于:%是一个相对父元素计算得来 ...
- 轻松让HTML5可以显示桌面通知Notification非常实用
使用Notification的流程 1.检查浏览器是否支持Notification2.检查浏览器的通知权限3.如果权限不够则申请获取权限4.创建消息通知5.展示消息通知 Notification AP ...
- 通过原生js对DOM事件的绑定的几种方式总汇
在网页开发中经常会有交互操作,比如点击一个dom元素,需要让js对该操作做出相应的响应,这就需要对Dom元素进行事件绑定来进行处理,js通常有三种常用的方法进行事件绑定:在DOM元素中直接绑定:在Ja ...