迭代器适配器{(插入迭代器back_insert_iterator)、IO流迭代器(istream_iterator、ostream_iterator)}
一、迭代器适配器
反向迭代器
插入迭代器
IO流迭代器
其中反向迭代器可以参考以前的文章。
二、插入迭代器
插入迭代器实际上是一个输出迭代器(*it=; ++)
back_insert_iterator
back_inserter
front_insert_iterator
front_inserter
先来看示例:
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
#include <iostream>
#include <vector> #include <algorithm> using namespace std; void ShowVec(const vector<int> &v) back_insert_iterator<vector<int> > bii(v); back_insert_iterator<vector<int> > bii2(v2); back_inserter(v) = 7; copy(v.begin(), v.end(), back_inserter(v2)); return 0; |
查看back_insert_iterator 类的定义:
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
// TEMPLATE CLASS back_insert_iterator
template<class _Container> class back_insert_iterator : public _Outit { // wrap pushes to back of container as output iterator public: typedef _Container container_type; typedef typename _Container::reference reference; typedef _Range_checked_iterator_tag _Checked_iterator_category; explicit back_insert_iterator(_Container &_Cont) back_insert_iterator<_Container> &operator=( back_insert_iterator<_Container> &operator*() back_insert_iterator<_Container> &operator++() back_insert_iterator<_Container> operator++(int) protected: |
container->push_back(_Val); 即调用了容器的push_back 函数, 所以可以直接写 bii = 6; 即将6压入容器末尾。程序中还调用了copy
函数,回顾copy 源码,主要是以下代码:
for (; _First != _Last; ++_Dest, ++_First)
*_Dest = *_First;
其中,_First 和 _Last 分别是v.begin() 和 v.end(), _Dest 是 bii2,上面也说了,*_Dest 返回的是自身,而且++_Dest 返回的也是自
身,从_First 遍历到 _Last ,调用back_insert_iterator 类的operator=,即不断地执行container->push_back(_Val);
容器的元素位置会
自动移动。
再来看back_inserter 函数:
|
1
2 3 4 5 6 7 |
// TEMPLATE FUNCTION back_inserter
template<class _Container> inline back_insert_iterator<_Container> back_inserter(_Container &_Cont) { // return a back_insert_iterator return (std::back_insert_iterator<_Container>(_Cont)); } |
实际上返回的也是一个back_insert_iterator 对象,所以能直接替换掉bii2。
当然了,与back 配对的就是front,back 是末尾插入,front 是头端插入,需要注意的是front_insert_iterator 的operator= 调用了
push_front 函数,故如vector 是没有实现push_front 的,不能使用front_insert_iterator ,而list 和 deque 是可以使用的。
示例代码如下:
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#include <iostream>
#include <vector> #include <list> #include <algorithm> using namespace std; void ShowList(const list<int> &v) int main(void) front_insert_iterator<list<int> > fii(l); copy(l.begin(), l.end(), front_inserter(ll)); |
三、IO流迭代器
输出流迭代器(ostream_iterator)
*it=; ++
输入流迭代器(istream_iterator)
=*it; ->; ++; ==; !=
直接来看示例代码:
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <iostream>
#include <vector> #include <list> #include <algorithm> using namespace std; int main(void) // copy from cin to vector // copy from vector to cout return 0; |
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
// TEMPLATE CLASS istream_iterator
template < class _Ty, class _Elem = char, class _Traits = char_traits<_Elem>, class _Diff = ptrdiff_t > class istream_iterator : public iterator < input_iterator_tag, _Ty, _Diff, const _Ty *, const _Ty & > { // wrap _Ty extracts from input stream as input iterator typedef istream_iterator<_Ty, _Elem, _Traits, _Diff> _Myt; public: typedef _Elem char_type; typedef _Traits traits_type; typedef basic_istream<_Elem, _Traits> istream_type; #if _SECURE_SCL istream_iterator() istream_iterator(istream_type &_Istr) const _Ty &operator*() const return (_Myval); const _Ty *operator->() const _Myt &operator++() _Getval(); protected: istream_type *_Myistr; // pointer to input stream |
istream_iterator 类有两个成员,一个是输入流对象指针,一个是输入的值,如
istream_iterator<int>(cin)
调用构造函数,初始化_Myistr,且通过函数_Getval() 初始化_Myval,_Getval() 调用输入流的
operator>>
将键盘输入的值赋予_Myval。而 istream_iterator<int>() 呢初始化_Myistr 为0,此时_Myval 被忽略。
回顾copy 源码,主要是以下代码:
for (; _First != _Last; ++_Dest, ++_First)
*_Dest = *_First;
此时_First 和 _Last 是 istream_iterator<int>
类型,_Dest是back_insert_iterator 类型,而判断_First 和 _Last 是否相等,其实
istream_iterator<int>(cin)
的_Myistr 被置为0,此时本来 istream_iterator<int>()
的_Myistr 就为0,故相等,不再继续执行下去。
如果不等,即输入正确的话,*First 调用istream_iterator 类的operator* 直接返回_Myval ,接着调用back_insert_iterator
类的
istream_iterator 类的
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
// TEMPLATE CLASS ostream_iterator
template<class _Ty, class _Elem = char, class _Traits = char_traits<_Elem> > class ostream_iterator : public _Outit { // wrap _Ty inserts to output stream as output iterator public: typedef _Elem char_type; typedef _Traits traits_type; typedef basic_ostream<_Elem, _Traits> ostream_type; #if _SECURE_SCL ostream_iterator(ostream_type& _Ostr, ostream_iterator<_Ty, _Elem, _Traits>& operator=(const _Ty& _Val) return (*this); ostream_iterator<_Ty, _Elem, _Traits>& operator*() ostream_iterator<_Ty, _Elem, _Traits>& operator++() protected: const _Elem *_Mydelim; // pointer to delimiter string (NB: not freed) |
ostream_iterator 类也有两个成员,一个是输出流对象指针,一个是字符串指针,看上面的copy 代码,此时_First 和 _Last
分别是v.begin() 和 v.end(),_Dest是 ostream_iterator<int> 类型,*_Dest
返回自身,++_Dest 也返回自身,而在operator= 函数中
*_Myostr << _Val;
if (_Mydelim != 0)
*_Myostr << _Mydelim;
即判断如果还有传入字符串,则在输出元素值之后,还伴随着字符串的输出。所以示例代码中的输出是伴随着空格的。
参考:
C++ primer 第四版
Effective C++ 3rd
C++编程规范
迭代器适配器{(插入迭代器back_insert_iterator)、IO流迭代器(istream_iterator、ostream_iterator)}的更多相关文章
- 第十五篇:流迭代器 + 算法灵活控制IO流
前言 标准算法配合迭代器使用太美妙了,使我们对容器(数据)的处理更加得心应手.那么,能不能对IO流也使用标准算法呢?有人认为不能,他们说因为IO流不是容器,没有迭代器,故无法使用标准算法.他们错了,错 ...
- 流迭代器 + 算法灵活控制IO流
前言 标准算法配合迭代器使用太美妙了,使我们对容器(数据)的处理更加得心应手.那么,能不能对IO流也使用标准算法呢?有人认为不能,他们说因为IO流不是容器,没有迭代器,故无法使用标准算法.他们错了,错 ...
- C++STL:流迭代器
流迭代器是一种迭代器适配器.istream_iterator用于读取输入流,ostream_iterator用于写输出流.这些迭代器将它们所对应的流视为特定类型的元素序列.使用流迭代器时,可以用泛型算 ...
- 【C++ STL应用与实现】18: 怎样使用迭代器适配器
本系列文章的文件夹在这里:文件夹. 通过文件夹里能够对STL整体有个大概了解 前言 本文介绍了STL中的迭代器适配器(iterator adapter)的概念及其用法演示样例.迭代器适配器能够和标准库 ...
- STL 迭代器适配器(iterator adapter)
iterator adapter graph LR iterator --- reverse_iterator iterator --- Insert_iterator iterator --- io ...
- function adapter(函数适配器)和迭代器适配器
所谓function adapter(函数适配器)是指能够将不同的函数对象(或是和某值或某寻常函数)结合起来的东西,它自身也是个函数对象. 迭代器适配器 运用STL中的迭代器适配器,可以使得算法能够 ...
- 迭代器适配器(一)back_inserter和front_inserter的实现
本文讨论back_inserter和front_inserter的实现. 当我们调用copy函数的时候,要确保目标容器具有足够大的空间,例如: //将other的所有元素拷贝到以coll.begin( ...
- STL标准库-迭代器适配器
技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性 这次主要介绍一下迭代器适配器.以reverse_iterator(反向迭代器),insert_iterator(插入迭代器),o ...
- list的迭代器能解决并发问题,collection 的迭代器不能解决并发问题,for可以解决并发问题
list的迭代器能解决并发问题,collection 的迭代器不能解决并发问题 为什么list支持add,collection不支持 例如有两个人同时添加第三个元素 list的迭代器能锁定线程 只有等 ...
随机推荐
- ExtJS4.2:自定义主题 入门
背景 用过 ExtJs 的朋友都有一种趋势:审美疲劳,好在 Ext4.1 之后的版本提供了快速自定义主题的功能,本文的内容主要来自:http://docs.sencha.com/extjs/4.2.2 ...
- Go:《Go语言 云动力》
背景 中秋快速的读了一遍<Go语言 云动力>,对Go有一下几点感觉: 在静态类型和动态类型之间取得了非常好的平衡,隐式接口实现会被后续的语言借鉴(希望C#能借鉴一下). 缺乏异常处理机制, ...
- DedeCms V5.6 plus/advancedsearch.php 任意sql语句执行漏洞
漏洞版本: DedeCms V5.6 漏洞描述: DedeCMS内容管理系统软件采用XML名字空间风格核心模板:模板全部使用文件形式保存,对用户设计模板.网站升级转移均提供很大的便利,健壮的模板标签为 ...
- 用mysqlslap对MySQL进行压力测试
MySQL5.1地的确提供了好多有力的工具来帮助我们DBA进行数据库管理.现在看一下这个压力测试工具mysqlslap.关于他的选项手册上以及--help介绍的很详细.我解释一下一些常用的选项.这里要 ...
- 如何利用WebClient模拟登陆CSRF控制的网站
一般我们都是利用WebRequest这个类来向服务器进行数据的POST,不过很多情况下相应的服务器都有验证,看你是不是登陆,是不是来自同一个域,这些都简单,我们可以更改其属性来达到欺骗服务器.不过如果 ...
- tomcat控制台启动成功但是却访问不了主页
从杭州来京出差,也许是因为春节将至,也或许是由于携带的一点点小情绪致使自己丧失了理智,So 那就开始吧.............北京有些地方也不错的. 需要帮同事在客户这边搭建一个Java proje ...
- [AngularJS] $scope.$watch
/** * Created by Answer1215 on 11/13/2014. */ function MainCtrl($scope){ function isLongEnough (pwd) ...
- ExtAspNet下通过文档路径实现文档的下载
<ext:Button ID="Button1" runat="server" Text="Button" OnClick=" ...
- Linux系统配置VSFTP软件详解
Linux系统配置VSFTP软件详解 出处 http://www.sudu.cn/service/detail.php?id=11656 vsftpd.conf 是vsftpd的配置文件,用来控制vs ...
- 我的GTD起步
最初因为工作进程漫无目的的逛网页,私人生活也一团乱麻,无法做自己想要的事情,这才开始接触个人管理和时间管理. 慢慢的也开始建立一套自己的体系,但是和之前改变不是很大,后来看了<小强升职记> ...