文档章节

STL: iterator适配器(1).

SHIHUAMarryMe
 SHIHUAMarryMe
发布于 2016/08/14 00:07
字数 1066
阅读 18
收藏 0

首先我们先从最简单的Iterator适配器来开始:

  • Insert(安插型)迭代器
template< class Container >
class insert_iterator;

std::insert_iterator::insert_iterator

//接受一个Container,和一个该容器的Iterator.
explicit insert_iterator( Container& c, typename Container::iterator i );
	

每次的插入操作相当于调用: c.insert(i, value);也就是说该容器必须支持insert操作.

接下来是std::insert_iterator支持的操作:

*iterator : 空操作, 内部实现为 return *this;

iter = value : 安插value 到构造函数指定的位置之前或者之后(之所以是之前或者之后,这个要看具体的container).其实也等价于 *iterator = value.

++iter : 空操作,内部实现为return *this;

iter++ : 空操作,内部实现为return *this;

  • Back_insert迭代器
template< class Container >
class back_insert_iterator;

std::back_insert_iterator::back_insert_iterator

explicit back_insert_iterator( Container& c );
	

相当于调用c.push_back(value); 这也就意味着我们的容器必须支持该操作.

接下来是std::back_insert_iterator支持的操作:

*iterator : 空操作, 内部实现为 return *this;

iter = value : 安插value 到构造函数指定的位置之前或者之后(之所以是之前或者之后,这个要看具体的container).其实也等价于 *iterator = value.

++iter : 空操作,内部实现为return *this;

iter++ : 空操作,内部实现为return *this;

  • Front_insert迭代器
template< class Container >
class front_insert_iterator;

 std::front_insert_iterator::front_insert_iterator

explicit front_insert_iterator( Container& c );

每次插入操作其实就是调用c.front_insert(value);也就是说我们给定的Container必须支持front_insert操作.

接下来是std::front_insert_iterator支持的操作:

*iterator : 空操作, 内部实现为 return *this;

iter = value : 安插value 到构造函数指定的位置之前或者之后(之所以是之前或者之后,这个要看具体的container).其实也等价于 *iterator = value.

++iter : 空操作,内部实现为return *this;

iter++ : 空操作,内部实现为return *this;

Demo

#include <iostream>
#include <vector>
#include <forward_list>
#include <iterator>

int main()
{
	std::forward_list<int> f_list;
	std::front_insert_iterator<std::forward_list<int>> f_insert(f_list);
	for (int i = 0; i < 10; ++i) {
		*f_insert = i;
		++f_insert;
	}

	for (const int& value : f_list) {
		std::cout << value << " ";
	}
	std::cout << std::endl;

	std::vector<int> vec;
	std::insert_iterator<std::vector<int>> insert(vec, vec.begin());
	for (int i = 0; i < 10; ++i) {
		*insert = i;
		++insert;
	}

	for (const int& value : vec) {
		std::cout << value << " ";
	}
	std::cout << std::endl;

	return 0;
}

Stream(串流)迭代器:

Stream迭代器是一种迭代器适配器,借用它,你可以把stream当成算法的来源端和目的端。更明确地说,一个istream迭代器可以用来从input istream读取元素,而一个ostream迭代器可以用来对output stream写入元素.

std::ostream_iterator

template< class T,
          class CharT = char,
          class Traits = std::char_traits<CharT>>
class ostream_iterator;

std::ostream_iterator::ostream_iterator

ostream_iterator(ostream_type& stream, const CharT* delim)
	 	
ostream_iterator(ostream_type& stream)

其支持的操作:

*iterator : 空操作,其内部实现为return *this;

iterator = value : 将value的值写到ostream中去: ostream<<value.

++iterator : 空操作,内部实现为: return *this;

iterator++ : 空操作,其内部实现为return *this;

--------------------------------我是分割线-----------------------------------------

std::istream_iterator

template< class T,
          class CharT = char,
          class Traits = std::char_traits<CharT>,
          class Distance = std::ptrdiff_t >
class istream_iterator;

std::istream_iterator::istream_iterator

istream_iterator();

constexpr istream_iterator(); //(since C++11, only if T is literal type)

istream_iterator( istream_type& stream );
	
istream_iterator( const istream_iterator& other ) = default;

其支持的操作:

其中特别需要注意的是->和*操作.

const T& operator*() const;
	
const T* operator->() const;

*iter : 返回之前读取的值(如果构造函数并未立刻读取一个值,则本次执行读取任务).

iter->member : 返回之前读取的元素的成员.

++iter : 读取下一个值,并返回该值的位置.

iter++ : 返回下前一个读取位置,读取下一个值.

iter1 == iter2 : 检查iter1 和 iter2是否相等.

iter1 != iter2 : 检查iter1 和 iter2是否不等.

建立std::istream_iterator的时候,你必须提供一个input stream 作为实参,迭代器将从其中读取数据。然后它便经由input stream 的寻常接口,使用operator>>读取元素。但是读取动作有可能失败(可能读取到文件尾部,也可能读取错误),此外算法的数据来源端也需要一个终点,为了解决这个 问题我们可以使用一个名为: end of stream迭代器他以std::istream_iterator的default构造函数产出. std::istream_iterator只要有任何一次读取失败,就会变成 end of stream迭代器。

Demo for std::istream_iterator and std::ostream_iterator

#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>

int main()
{
	std::ostream_iterator<int> intPrint(std::cout, "\n");
	*intPrint = 20;

	std::istream_iterator<int> writeInt(std::cin);
	std::istream_iterator<int> writeEOF;
	while (writeInt != writeEOF) {
		std::cout << "value: " << *writeInt << std::endl;
		++writeInt;
	}

	return 0;
}

 

© 著作权归作者所有

共有 人打赏支持
SHIHUAMarryMe
粉丝 13
博文 163
码字总数 137219
作品 0
武汉
程序员
私信 提问
C++ STL编程轻松入门 5

2.2.3 第三版:唯美主义的杰作   事态的发展有时候总会趋向极端,这在那些唯美主义者当中犹是如此。首先声明,我并不是一个唯美主义者,提供第二版程序的改进版,完全是为了让你更深刻的感...

暖冰
2015/11/21
0
0
C++语言学习之STL 的组成

STL有三大核心部分:容器(Container)、算法(Algorithms)、迭代器(Iterator),容器适配器(container adaptor),函数对象(functor),除此之外还有STL其他标准组件。通俗的讲: 容器:装...

杨坤乾
2014/02/11
0
0
提升 C++ 技能的 7 种方法

本文由伯乐在线 -精算狗 翻译,艾凌风 校稿。未经许可,禁止转载! 英文出处: Jonathan Boccara。欢迎加入 翻译组。 夏天时常会谈到大海、太阳、沙滩、大山或者你的家庭住宅。更充裕的时间也...

伯乐在线
2017/08/24
0
0
C++ STL学习——vector

学过C++的人肯定会很熟悉STL标准模板库,STL其实就是封装了一系列的接口,供我们调用。很多函数或者算法的实现不需要我们从头开始写,大大提高我们的编程效率。这篇博客在简单介绍STL的情况下...

chenyufeng1991
2016/08/21
0
0
STL list链表的用法详解

------------------------------------------------------------------------------- 原来... STL list链表的用法详解 本文以List容器为例子,介绍了STL的基本内容,从容器到迭代器,再到普通...

nao
2014/04/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

通过Docker容器连接代理Wormhole

Wormhole 是一个能识别命名空间的由 Socket 激活的隧道代理。可以让你安全的连接在不同物理机器上的 Docker 容器。可以用来完成一些有趣的功能,例如连接运行在容器本机的服务或者在连接后创...

Linux就该这么学
18分钟前
1
0
从架构到平台, POWER 9处理器最全解读

本文根据IBM中国芯片设计部门高级经理尹文,在「智东西公开课」的超级公开课IBM专场《POWER 9-认知时代的驱动力》 上的系统讲解整理而来。 本次讲解中,尹文老师从内核微架构、总线互连、异构...

Mr_zebra
21分钟前
1
0
openjdk和oraclejdk有什么区别吗?

1.授权协议的不同:OpenJDK采用GPL V2协议放出,而SUN JDK则采用JRL放出。两者协议虽然都是开放源代码的,但是在使用上的不同在于GPL V2允许在商业上使用,而JRL只允许个人研究使用。 2.Open...

吴伟祥
22分钟前
2
0
c++基类析构函数要声明为virtual的原因

更深层的原因不知道,不过标准规定,如果不声明为virtual,那么将会导致未定义行为。个人测试结果表明,如果不声明为virtual,那么派生类的析构函数将不会得到调用

安非他命
28分钟前
1
0
CentOS 7下protobuf的源码编译安装

protobuf的github地址:https://github.com/google/protobuf支持多种语言,有多个语言的版本,本文采用的是在CentOS 7下编译源码进行安装。 github上有详细的安装说明:https://github.com/...

xtof
35分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部