文档章节

STL: iterator适配器(2).

SHIHUAMarryMe
 SHIHUAMarryMe
发布于 2016/08/14 17:15
字数 776
阅读 16
收藏 0
点赞 0
评论 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
粉丝 12
博文 165
码字总数 138772
作品 0
武汉
程序员
C++ STL学习——vector

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

chenyufeng1991 ⋅ 2016/08/21 ⋅ 0

ICE第二篇--一个"hello world"的简单例子

1 本文介绍一个hello world输出的例子。 ice应用的步骤如下: 编写 Slice 定义并编译它。 编写服务器并编译它。 编写客户并编译它。 基本框架图示: 本文代码图示: 需要注意的概念: servan...

moki_oschina ⋅ 06/06 ⋅ 0

VS2010/MFC编程入门教程之目录和总结(鸡啄米)

鸡啄米的这套VS2010/MFC编程入门教程到此就全部完成了,虽然有些内容还未涉及到,但帮助大家进行VS2010/MFC的入门学习业已足够。以此教程的知识为基础,学习VS2010/MFC较为深入的内容已非难事...

weixin_40647819 ⋅ 05/23 ⋅ 0

Effective C++ 笔记(1):视C++为语言联邦

条款一(clause 1) 将C++视为语言联邦:提出了一种将C++分为四种不同次语言的观念,四种次语言分别是: 1、C语言,面向过程的语言,C++完全向下兼容C,在C++中单纯使用C语言的语法除了遵守的一...

oldpan ⋅ 2017/09/10 ⋅ 0

大神有话说之c++,还在迷茫的朋友可以来看一下

C++ 是一种中级语言,它是由 Bjarne Stroustrup 于 1979 年在贝尔实验室开始设计开发的。C++ 进一步扩充和完善了 C 语言,是一种面向对象的程序设计语言。C++ 可运行于多种平台上,如 Window...

悟空_b201 ⋅ 05/30 ⋅ 0

C语言/C++编程学习强势之处的体现

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你看世界 ⋅ 05/12 ⋅ 0

C语言/C++永远都不会过时的编程语言

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你看世界 ⋅ 03/30 ⋅ 0

C语言/C++编程学习未来之路

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你看世界 ⋅ 03/30 ⋅ 0

C语言/C++编程学习:环境设置

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你看世界 ⋅ 06/05 ⋅ 0

C语言/C++编程新手学习常见问题

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你看世界 ⋅ 05/11 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Boost库编译应用

版本:Boost 1.66.0 Windows库编译 官网指南:直接执行bootstrap.bat处理文件即可,可以我却遇到一堆的问题。 环境:Windows 10 + Visual Studio 2017 Boost编译出来库命名 boost库生成文件命...

水海云 ⋅ 19分钟前 ⋅ 0

解决Eclipse发布到Tomcat丢失依赖jar包的问题

如果jar文件是以外部依赖的形式导入的。Eclipse将web项目发布到Tomcat时,是不会自动发布这些依赖的。 可以通过Eclipse在项目上右击 - Propertics - Deployment Assembly,添加“Java Build ...

ArlenXu ⋅ 19分钟前 ⋅ 0

iview tree组件层级过多时可左右滚动

使用vue+iview的tree组件,iview官网iview的tree树形控件 问题描述:tree层级过多时左右不可滚动 问题解决:修改overflow属性值 .el-tree-node>.el-tree-node_children { overflow: vi...

YXMBetter ⋅ 21分钟前 ⋅ 0

分布式锁

1.通过数据库实现 http://www.weizijun.cn/2016/03/17/%E8%81%8A%E4%B8%80%E8%81%8A%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81%E7%9A%84%E8%AE%BE%E8%AE%A1/ 2.ZK实现:curator-recipes分布式锁的......

素雷 ⋅ 29分钟前 ⋅ 0

Sublime Text3 快捷键

选择类 Ctrl+D 选中光标所占的文本,继续操作则会选中下一个相同的文本。 Alt+F3 选中文本按下快捷键,即可一次性选择全部的相同文本进行同时编辑。举个栗子:快速选中并更改所有相同的变量名...

AndyZhouX ⋅ 36分钟前 ⋅ 0

XamarinAndroid组件教程RecylerView自定义适配器动画

XamarinAndroid组件教程RecylerView自定义适配器动画 如果RecyclerViewAnimators.Adapters命名空间中没有所需要的适配器动画,开发者可以自定义动画。此时,需要让自定义的动画继承Animation...

大学霸 ⋅ 36分钟前 ⋅ 0

eureka 基础(二)

使用Eureka服务器进行身份验证 如果其中一个eureka.client.serviceUrl.defaultZone网址中包含一个凭据(如http://user:password@localhost:8761/eureka)),HTTP基本身份验证将自动添加到您...

明理萝 ⋅ 39分钟前 ⋅ 1

Kubernetes(五) - Service

Kubernetes解决的另外一个痛点就是服务发现,服务发现机制和容器开放访问都是通过Service来实现的,把Deployment和Service关联起来只需要Label标签相同就可以关联起来形成负载均衡,基于kuberne...

喵了_个咪 ⋅ 39分钟前 ⋅ 0

更新队友POM文件后报错

打开报错的地方的pom及其引用方法所在文件的pom,观察其版本号是否一致,不一致进行更改

森火 ⋅ 52分钟前 ⋅ 0

IDEA使用sonarLint

一、IDEA如何安装SonarLint插件 1.打开 Idea 2.点击【File】 3.点击【Settings】 4.点击【Plugins】 5.在搜索栏中输入“sonarlint”关键字 6.点击【Install】进行安装 7.重启Idea 二、IDEA如...

开源中国成都区源花 ⋅ 58分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部