文档章节

STL: iterator适配器(2).

SHIHUAMarryMe
 SHIHUAMarryMe
发布于 2016/08/14 17:15
字数 776
阅读 16
收藏 0

自C++11来iterator越来越成为标准库中的重要一环.

iterator分为(这里只是粗略的提一下,下一篇会详细介绍):

Output-iterator, Input-iterator, Froward-iterator, Bidirectional-iterator, Random-access-iterator.这5种迭代器每种迭代器的能力不同,因此有的时候达不到我们的要求。

标准库提供了iterator相关的辅助函数:

  • advance()
template< class InputIt, class Distance >
constexpr void advance( InputIt& it, Distance n );

1,增加给定的迭代器使其向前或者向后移动n个位置.

2,对于Bidirectional-iterator和Random-access-iterator来说,n可以为负值也可以为正值.

3,Distance是个template类型。通常它必须是个整数类型,因为可能会调用++, <, --等操作还要和0 做比较.

4,advance()并不检查迭代器时候超过给定序列的end()(因为迭代器通常不知道其操作的容器,因此无从检查).所以,调用advance()有可能导致不明确的行为。

Demo for advance()

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

int main()
{

	//case 1: Forward_iterator!!!!
	std::forward_list<int> fList{ 1, 2, 3, 5, 6, 7, 9 };

	//注意std::forward_list里面的iterator和const_iterator都是 Forward_iterator类型的不支持 -, --等操作.
	std::forward_list<int>::const_iterator iter = fList.cbegin();
	std::cout << "value1:  " << *iter << std::endl;
	std::cout << "value2:  " << *(++iter) << std::endl;

	//error不支持递减.
	//std::cout << "value3:  " << *(--iter) << std::endl;

	//但是我们现在每次递增一个太慢了我们想要一次跨越几个.
	std::advance(iter, 3);
	std::cout << "value3: " << *iter << std::endl;

	//case 2: Random-access-iterator!!!!!!!!!!
	std::vector<int> vec{ 1, 2, 3, 4, 5, 6, 8 };
	
	//注意std::vector里面的iterator和const_iterator都是Random-access-iterator.
	std::vector<int>::const_iterator v_iter = vec.cbegin();
	std::cout << "value4:  " << *v_iter << std::endl;
	std::cout << "value5:  " << *(++v_iter) << std::endl;
	std::cout << "value6:  " << *(--v_iter) << std::endl;

	std::advance(v_iter, 3);
	std::cout << "value7:  " << *v_iter << std::endl;
	std::advance(v_iter, -1); 
	std::cout << "value8:  " << *v_iter << std::endl;

	return 0;
}

Another Demo:

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

int main()
{
	std::istream_iterator<std::basic_string<char>> cinPos(std::cin);
	std::ostream_iterator<std::basic_string<char>> coutPos(std::cout, " ");

	while (cinPos != std::istream_iterator<std::basic_string<char>>()) {
		std::advance(cinPos, 2);

		if (cinPos != std::istream_iterator<std::basic_string<char>>()) {
			*coutPos = *cinPos++;
		}
	}

	std::cout << std::endl;

	return 0;
}
  • next()和prev()

std::next()

template< class InputIt >
constexpr InputIt next( InputIt it, typename std::iterator_traits<InputIt>::difference_type n = 1 );

1,导致Forward迭代器或者Input迭代器向前移动1个或者n个位置

2,如果处理的是Bidirectional-iterator和Random-access-iterator的话n的值可以为负值(导致后退).

3,n的类型是 typename std::iterator_traits<iter>::difference_type.

4,注意next()并不检查是否会跨越序列的end().

std::prev()

template< class BidirIt >
constexpr BidirIt prev(
  BidirIt it,
  typename std::iterator_traits<BidirIt>::difference_type n = 1 );

1,导致Bidirectional迭代器后退1个或者n个位置.

2,n可以为负值,导致向前移动。

3,Dist的类型为 typename std::iterator_traits<BidirIt>::difference_type.

4,注意prev()并不检查是否会超过序列的begin()或者cbegin().

 

//std::distance()作为了解就行了 性能并不好。。。

std::distance()

template< class InputIt >
constexpr typename std::iterator_traits<InputIt>::difference_type
    distance( InputIt first, InputIt last );

1,返回两个iterator first和last之间的距离.

2,first和last必须指向同一个迭代器.

3,如果不是Random-access-iterator,则从first开始前进必须能够到达last,亦last的位置必须在first之后,或者与first的位置相同.

4,该函数的返回类型为: typename std::iterator_traits<Itr>::difference_type

 

© 著作权归作者所有

共有 人打赏支持
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

没有更多内容

加载失败,请刷新页面

加载更多

给女朋友讲解什么是Optional【JDK 8特性】

前言 只有光头才能变强 前两天带女朋友去图书馆了,随手就给她来了一本《与孩子一起学编程》的书,于是今天就给女朋友讲解一下什么是Optional类。 至于她能不能看懂,那肯定是看不懂的。(学到...

Java3y
11分钟前
0
0
2019年六大新兴信息安全方向

导读 黑客攻击和网络犯罪的威胁正在不断升级,相应的技术“军备竞赛”正愈演愈烈,对于信息安全从业人员来说,掌握最新的信息安全工具,是在信息安全战争中生存下来的关键所在。 从特朗普的手...

问题终结者
17分钟前
0
0
redis扩展-自定义PropertyPlaceholderConfigurer,在spring属性注入之前,手动将properteis合并到spring容器中

背景:spring容器启动过程中,通过PropertyPlaceholderConfigurer读取properties配置文件,并将properties配置文件中的值注入spring bean的属性中, PropertyPlaceholderConfigurer使用方式多...

燃犀
19分钟前
0
0
PostgreSQL SPI 中的错误处理

PostgreSQL SPI 用于在 C 或是其他编程语言编写的扩展函数(存储过程)中调用数据库本身的解析器、规划器和执行器的功能,以及对 SQL 语句进行执行。 在最重要的一个函数 SPI_execute 的文档...

helloclia
20分钟前
0
0
深入理解Java内存模型

1 内存模型产生背景 在介绍Java内存模型之前,我们先了解一下物理计算机中的并发问题,理解这些问题可以搞清楚内存模型产生的背景。物理机遇到的并发问题与虚拟机中的情况有不少相似之处,物...

小刀爱编程
34分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部