当前位置: 首页 > 编程日记 > 正文

C++/C++11中头文件iterator的使用

<iterator>是C++标准程序库中的一个头文件,定义了C++ STL标准中的一些迭代器模板类,这些类都是以std::iterator为基类派生出来的。迭代器提供对集合(容器)元素的操作能力。迭代器提供的基本操作就是访问和遍历。迭代器模拟了C++中的指针,可以有++运算,用*(解引用算符,deference)或->算符来访问容器中的元素。容器中元素如果改变了所用内存,也不影响绑定的迭代器指向正确的位置。因此,迭代器实际上更像是句柄(handler)。迭代器允许C++程序以统一的方式处理不同的数据结构。迭代器充当容器和通用算法之间的中介。而不是对特定数据类型进行操作,算法被定义为在一个迭代器类型指定的范围内运行。任何满足迭代器要求的数据结构都可以通过算法进行操作。

STL的迭代器实现了设计模式中的”迭代器模式”,即顺序访问一个聚合中的元素,又不暴露聚合的实现细节。

迭代器支持以不同方法遍历聚合类型。例如,对一颗树数据类型,可以有前序、中序、后序遍历的迭代器。同一个聚合类型的对象上,可以同时有多个迭代器,各自保持不同的遍历状态。在不同的聚合类型上实现的迭代器具有标准的对外接口,这给STL中的算法使用迭代器提供了可能。

一共支持五种迭代器:输入迭代器(*iter解引用后只能用作右值)、输出迭代器(*iter解引用后只能用作左值)、前向迭代器(具有输入迭代器、输出迭代器的所有功能,且可以反复遍历操作,支持对同一个元素的多次读写)、双向迭代器(是在前向迭代器的基础上,多了单步向后遍历的能力)、随机访问迭代器(在双向迭代器基础上,具有直接访问各数据元素的能力。随机迭代器增加了”迭代器算术运算”)。

std::input_iterator_tag:空类,标识一个迭代器的类别为输入迭代器。

std::output_iterator_tag:空类,标识一个迭代器的类别为输出迭代器。

std::forward_iterator_tag:空类,标识一个迭代器的类别为前向迭代器。

std::bidirectional_iterator_tag:空类,标识一个迭代器的类别为双向迭代器。

std::random_access_iterator_tag:空类,标识一个迭代器的类别为随机迭代器。

下面是从其它文章中copy的<iterator>测试代码,详细内容介绍可以参考对应的reference:

#include "iterator.hpp"
#include <iterator>
#include <iostream>
#include <typeinfo>
#include <list>
#include <vector>
#include <algorithm>
#include <deque>
#include <string>// reference: http://www.cplusplus.com/reference/iterator/namespace iterator_ {
///
class MyIterator : public std::iterator<std::input_iterator_tag, int>
{
public:MyIterator(int* x) :p(x) {}MyIterator(const MyIterator& mit) : p(mit.p) {}MyIterator& operator++() { ++p; return *this; }MyIterator operator++(int) { MyIterator tmp(*this); operator++(); return tmp; }bool operator==(const MyIterator& rhs) const { return p == rhs.p; }bool operator!=(const MyIterator& rhs) const { return p != rhs.p; }int& operator*() { return *p; }
private:int* p;
};int test_iterator_1()
{// std::iterator: 迭代器基类int numbers[] = { 10, 20, 30, 40, 50 };MyIterator from(numbers);MyIterator until(numbers + 5);for (MyIterator it = from; it != until; it++)std::cout << *it << ' ';std::cout << '\n';return 0;
}/
int test_iterator_2()
{// std::iterator_traits: 定义迭代器属性typedef std::iterator_traits<int*> traits;if (typeid(traits::iterator_category) == typeid(std::random_access_iterator_tag))std::cout << "int* is a random-access iterator" << std::endl;;return 0;
}///
int test_iterator_3()
{// std::advance: 将迭代器推进到n个元素位置,可以是负值std::list<int> mylist;for (int i = 0; i<10; i++) mylist.push_back(i * 10);std::list<int>::iterator it = mylist.begin();std::advance(it, 5);std::cout << "The sixth element in mylist is: " << *it << '\n'; // 50return 0;
}int test_iterator_4()
{// std::back_inserter: 构造一个在x的末尾插入新元素的后插入迭代器std::vector<int> foo, bar;for (int i = 1; i <= 5; i++) {foo.push_back(i); bar.push_back(i * 10);}std::copy(bar.begin(), bar.end(), std::back_inserter(foo));std::cout << "foo contains:";for (std::vector<int>::iterator it = foo.begin(); it != foo.end(); ++it)std::cout << ' ' << *it; // 1 2 3 4 5 10 20 30 40 50std::cout << '\n';return 0;
}//
int test_iterator_5()
{// std::begin: 返回指向序列中第一个元素的迭代器// std::end: 返回指向序列中过去的最后一个元素的迭代器int foo[] = { 10, 20, 30, 40, 50 };std::vector<int> bar;// iterate foo: inserting into barfor (auto it = std::begin(foo); it != std::end(foo); ++it)bar.push_back(*it);// iterate bar: print contents:std::cout << "bar contains:";for (auto it = std::begin(bar); it != std::end(bar); ++it)std::cout << ' ' << *it; // 10 20 30 40 50std::cout << '\n';return 0;
}//
int test_iterator_6()
{// std::distance: 计算first和last之间的元素数量std::list<int> mylist;for (int i = 0; i<10; i++) mylist.push_back(i * 10);std::list<int>::iterator first = mylist.begin();std::list<int>::iterator last = mylist.end();std::cout << "The distance is: " << std::distance(first, last) << '\n'; // 10return 0;
}int test_iterator_7()
{// std::front_inserter: 构造一个前插入迭代器,在x的开头插入新元素std::deque<int> foo, bar;for (int i = 1; i <= 5; i++) {foo.push_back(i); bar.push_back(i * 10);}std::copy(bar.begin(), bar.end(), std::front_inserter(foo));std::cout << "foo contains:";for (std::deque<int>::iterator it = foo.begin(); it != foo.end(); ++it)std::cout << ' ' << *it; // 50 40 30 20 10 1 2 3 4 5std::cout << '\n';return 0;
}//
int test_iterator_8()
{// std::inserter: 构造一个插入迭代器,从指向的位置开始,在连续的位置中插入新元素xstd::list<int> foo, bar;for (int i = 1; i <= 5; i++) {foo.push_back(i); bar.push_back(i * 10);}std::list<int>::iterator it = foo.begin();std::advance(it, 3);std::copy(bar.begin(), bar.end(), std::inserter(foo, it));std::cout << "foo contains:";for (std::list<int>::iterator it = foo.begin(); it != foo.end(); ++it)std::cout << ' ' << *it; // 1 2 3 10 20 30 40 50 4 5std::cout << '\n';return 0;
}int test_iterator_9()
{// std::make_move_iterator: 从it构造一个move_iterator对象std::vector<std::string> foo(3);std::vector<std::string> bar{ "one", "two", "three" };std::copy(std::make_move_iterator(bar.begin()), std::make_move_iterator(bar.end()), foo.begin());// bar now contains unspecified values; clear it:bar.clear();std::cout << "foo:";for (std::string& x : foo) std::cout << ' ' << x; // one two threestd::cout << '\n';return 0;
}//
int test_iterator_10()
{// std::next: 获取下一个元素的迭代器std::list<int> mylist;for (int i = 0; i<10; i++) mylist.push_back(i * 10);std::cout << "mylist:";std::for_each(mylist.begin(), std::next(mylist.begin(), 5), [](int x) {std::cout << ' ' << x; }); // 0 10 20 30 40 50std::cout << '\n';return 0;
}//
int test_iterator_11()
{// std::prev: 获取前一个元素的迭代器std::list<int> mylist;for (int i = 0; i<10; i++) mylist.push_back(i * 10);std::cout << "The last element is " << *std::prev(mylist.end()) << '\n'; // 90return 0;
}int test_iterator_12()
{// std::back_insert_iterator: 在容器末尾插入元素的迭代器std::vector<int> foo, bar;for (int i = 1; i <= 5; i++) {foo.push_back(i); bar.push_back(i * 10);}std::back_insert_iterator< std::vector<int> > back_it(foo);std::copy(bar.begin(), bar.end(), back_it);std::cout << "foo:";for (std::vector<int>::iterator it = foo.begin(); it != foo.end(); ++it)std::cout << ' ' << *it; // 1 2 3 4 5 10 20 30 40 50 std::cout << '\n';return 0;
}///
int test_iterator_13()
{// std::front_insert_iterator: 在容器开头插入元素的迭代器std::deque<int> foo, bar;for (int i = 1; i <= 5; i++) {foo.push_back(i); bar.push_back(i * 10);}std::front_insert_iterator< std::deque<int> > front_it(foo);std::copy(bar.begin(), bar.end(), front_it);std::cout << "foo:";for (std::deque<int>::iterator it = foo.begin(); it != foo.end(); ++it)std::cout << ' ' << *it; // 50 40 30 20 10 1 2 3 4 5std::cout << '\n';return 0;
}//
int test_iterator_14()
{// std::insert_iterator: 插入迭代器std::list<int> foo, bar;for (int i = 1; i <= 5; i++) {foo.push_back(i); bar.push_back(i * 10);}std::list<int>::iterator it = foo.begin();std::advance(it, 3);std::insert_iterator< std::list<int> > insert_it(foo, it);std::copy(bar.begin(), bar.end(), insert_it);std::cout << "foo:";for (std::list<int>::iterator it = foo.begin(); it != foo.end(); ++it)std::cout << ' ' << *it; // 1 2 3 10 20 30 40 50 4 5std::cout << '\n';return 0;
}///
int test_iterator_15()
{// std::istreambuf_iterator: 输入流缓存迭代器std::istreambuf_iterator<char> eos;                    // end-of-range iteratorstd::istreambuf_iterator<char> iit(std::cin.rdbuf()); // stdin iteratorstd::string mystring;std::cout << "Please, enter your name: ";while (iit != eos && *iit != '\n') mystring += *iit++;std::cout << "Your name is " << mystring << ".\n";return 0;
}///
int test_iterator_16()
{// std::istream_iterator: 从输入流读取连续元素的输入迭代器double value1, value2;std::cout << "Please, insert two values: ";std::istream_iterator<double> eos;              // end-of-stream iteratorstd::istream_iterator<double> iit(std::cin);   // stdin iteratorif (iit != eos) value1 = *iit;++iit;if (iit != eos) value2 = *iit;std::cout << value1 << "*" << value2 << "=" << (value1*value2) << '\n';return 0;
}///
int test_iterator_17()
{// std::move_iterator: 用于解引用(Dereference)到一个右值引用(Rvalue reference)的迭代器std::vector<std::string> foo(3);std::vector<std::string> bar{ "one", "two", "three" };typedef std::vector<std::string>::iterator Iter;std::copy(std::move_iterator<Iter>(bar.begin()), std::move_iterator<Iter>(bar.end()), foo.begin());// bar now contains unspecified values; clear it:bar.clear();std::cout << "foo:";for (std::string& x : foo) std::cout << ' ' << x; // one two threestd::cout << '\n';return 0;
}///
int test_iterator_18()
{// std::ostreambuf_iterator: 输出流缓存迭代器std::string mystring("Some text here...\n");std::ostreambuf_iterator<char> out_it(std::cout); // stdout iteratorstd::copy(mystring.begin(), mystring.end(), out_it); // Some text here...return 0;
}/
int test_iterator_19()
{// std::ostream_iterator: 顺序写入输出流的输出迭代器std::vector<int> myvector;for (int i = 1; i<10; ++i) myvector.push_back(i * 10);std::ostream_iterator<int> out_it(std::cout, ", ");std::copy(myvector.begin(), myvector.end(), out_it); // 10, 20, 30, 40, 50, 60, 70, 80, 90, return 0;
}///
int test_iterator_20()
{// std::reverse_iterator: 反向迭代器std::vector<int> myvector;for (int i = 0; i<10; i++) myvector.push_back(i);typedef std::vector<int>::iterator iter_type;// ? 0 1 2 3 4 5 6 7 8 9 ?iter_type from(myvector.begin());                     //   ^//         ------>iter_type until(myvector.end());                      //                       ^//std::reverse_iterator<iter_type> rev_until(from);     // ^//         <------std::reverse_iterator<iter_type> rev_from(until);     //                     ^std::cout << "myvector:";while (rev_from != rev_until)std::cout << ' ' << *rev_from++; // 9 8 7 6 5 4 3 2 1 0std::cout << '\n';return 0;
}} // namespace iterator_


GitHub:https://github.com/fengbingchun/Messy_Test

相关文章:

从多媒体技术演进看AI技术

&#xff08;图片付费下载自视觉中国&#xff09;文 / LiveVideoStack主编 包研在8月的LiveVideoStackCon2019北京开场致辞中&#xff0c;我分享了一组数据——把2019年和2017年两场LiveVideoStackCon上的AI相关的话题做了统计&#xff0c;这是数字从9.3%增长到31%&#xff0c;…

五. python的日历模块

一 .日历 import calendar# 日历模块# 使用# 返回指定某年某月的日历 print(calendar.month(2017,7))# July 2017 # Mo Tu We Th Fr Sa Su # 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# 返…

Linux下的Shell工作原理

为什么80%的码农都做不了架构师&#xff1f;>>> Linux系统提供给用户的最重要的系统程序是Shell命令语言解释程序。它不 属于内核部分&#xff0c;而是在核心之外&#xff0c;以用户态方式运行。其基本功能是解释并 执行用户打入的各种命令&#xff0c;实现用户与L…

C++/C++11中头文件functional的使用

<functional>是C标准库中的一个头文件&#xff0c;定义了C标准中多个用于表示函数对象(function object)的类模板&#xff0c;包括算法操作、比较操作、逻辑操作&#xff1b;以及用于绑定函数对象的实参值的绑定器(binder)。这些类模板的实例是具有函数调用运算符(functi…

飞天AI平台到底哪里与众不同?听听它的架构者怎么说

采访嘉宾 | 林伟 整理 | 夕颜 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 天下没有不散的宴席。 9 月 25 日&#xff0c;云栖大会在云栖小镇开始&#xff0c;历经三天的技术盛宴&#xff0c;于 9 月 27 日的傍晚结束。 三天、全球6.7万人现场参会、超1250万人…

浅谈 sessionStorage、localStorage、cookie 的区别以及使用

1、sessionStorage、localStorage、cookie 之间的区别 相同点 cookie 和 webStorage 都是用来存储客户端的一些信息不同点 localStorage localStorage 的生命周期是 永久的。也就是说 只要不是 手动的去清除。localStorage 会一直存储 sessionStorage 相反 sessionStorage 的生…

任务栏窗口和状态图标的闪动 z

Demo程序&#xff1a; 实现任务栏窗体和图标的闪动&#xff1a; 整个程序是基于Windows Forms的&#xff0c;对于任务栏右下角状态图标的闪动&#xff0c;创建了一个类型&#xff1a;NotifyIconAnimator&#xff0c;基本上是包装了Windows Forms中的NotifyIcon类型&#xff0c;…

深度学习中的最大似然估计简介

统计领域为我们提供了很多工具来实现机器学习目标&#xff0c;不仅可以解决训练集上的任务&#xff0c;还可以泛化。例如参数估计、偏差和方差&#xff0c;对于正式地刻画泛化、欠拟合和过拟合都非常有帮助。点估计&#xff1a;点估计试图为一些感兴趣的量提供单个”最优”预测…

简单粗暴上手TensorFlow 2.0,北大学霸力作,必须人手一册!

&#xff08;图片付费下载自视觉中国&#xff09; 整理 | 夕颜 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 【导读】 TensorFlow 2.0 于近期正式发布后&#xff0c;立即受到学术界与科研界的广泛关注与好评。此前&#xff0c;AI 科技大本营曾特邀专家回顾了 Te…

常见运维漏洞-Rsync-Redis

转载于:https://blog.51cto.com/10945453/2394651

zabbix笔记

&#xff08;1&#xff09;转载于:https://blog.51cto.com/zlong37/1406441

C++/C++11中头文件algorithm的使用

<algorithm>是C标准程序库中的一个头文件&#xff0c;定义了C STL标准中的基础性的算法(均为函数模板)。<algorithm>定义了设计用于元素范围的函数集合。任何对象序列的范围可以通过迭代器或指针访问。 std::adjacent_find&#xff1a;在序列中查找第一对相邻且值…

js filter 用法

filter filter函数可以看成是一个过滤函数&#xff0c;返回符合条件的元素的数组 filter需要在循环的时候判断一下是true还是false&#xff0c;是true才会返回这个元素&#xff1b; filter()接收的回调函数&#xff0c;其实可以有多个参数。通常我们仅使用第一个参数&#xff…

每30秒学会一个Python小技巧,GitHub星数4600+

&#xff08;图片付费下载自视觉中国&#xff09;作者 | xiaoyu&#xff0c;数据爱好者来源 | Python数据科学&#xff08;ID:PyDataScience&#xff09;很多学习Python的朋友在项目实战中会遇到不少功能实现上的问题&#xff0c;有些问题并不是很难的问题&#xff0c;或者已经…

Nginx自定义模块编写:根据post参数路由到不同服务器

Nginx可以轻松实现根据不同的url 或者 get参数来转发到不同的服务器&#xff0c;然而当我们需要根据http包体来进行请求路由时&#xff0c;Nginx默认的配置规则就捉襟见肘了&#xff0c;但是没关系&#xff0c;Nginx提供了强大的自定义模块功能&#xff0c;我们只要进行需要的扩…

深度学习中的贝叶斯统计简介

贝叶斯用概率反映知识状态的确定性程度。数据集能够被直接观测到&#xff0c;因此不是随机的。另一方面&#xff0c;真实参数θ是未知或不确定的&#xff0c;因此可以表示成随机变量。在观察到数据前&#xff0c;我们将θ的已知知识表示成先验概率分布(prior probability distr…

少走弯路:强烈推荐的TensorFlow快速入门资料(可下载)

&#xff08;图片付费下载自视觉中国&#xff09;作者 | 黄海广来源 | 机器学习初学者&#xff08;ID: ai-start-com&#xff09;知识更新非常快&#xff0c;需要一直学习才能跟上时代进步&#xff0c;举个例子&#xff1a;吴恩达老师在深度学习课上讲的TensorFlow使用&#xf…

有状态bean与无状态bean

在学习bean的作用域的时候&#xff0c;了解了这个问题。 bean5种作用域&#xff1a;分别是&#xff1a;singleton、prototype、request、session、gloabal session 接下来就讲一下有状态bean与无状态bean&#xff1a; 有状态会话bean &#xff1a;每个用户有自己特有的一个实例…

从Developer Removed From Sale 回到可下载状态的方法

2019独角兽企业重金招聘Python工程师标准>>> 如果你不小心点了”Remove“ 按钮&#xff0c;App的状态会变成"Developer Removed From Sale "&#xff0c;这时&#xff0c;即使更新应用也无法改变这个状态。想要让App恢复可下载状态&#xff0c;你需要尝试…

朴素贝叶斯分类器简介及C++实现(性别分类)

贝叶斯分类器是一种基于贝叶斯定理的简单概率分类器。在机器学习中&#xff0c;朴素贝叶斯分类器是一系列以假设特征之间强(朴素)独立下运用贝叶斯定理为基础的简单概率分类器。朴素贝叶斯是文本分类的一种热门(基准)方法&#xff0c;文本分类是以词频为特征判断文件所属类别或…

你当年没玩好的《愤怒的小鸟》,AI现在也犯难了

&#xff08;图片源自百度百科&#xff09;作者 | Ekaterina Nikonova&#xff0c;Jakub Gemrot译者 | Tianyu出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;现在说起《愤怒的小鸟》游戏&#xff0c;要把人的回忆一下拉扯到差不多十年前了。它是一款当时一经推出就广…

msf反弹shell

今天回顾了一下msf反弹shell的操作&#xff0c;在这里做一下记录和分享。(&#xffe3;︶&#xffe3;)↗ 反弹shell的两种方法 第一种Msfvenom实例&#xff1a; 1、msfconsole    #启动msf 2、msfvenom -p php/meterpreter/reverse_tcp LHOST<Your IP Address> LPOR…

mysql 5.5半同步复制功能部署

安装、配置Semi-sync Replication在两台主机上安装好MySQL5.5&#xff0c;编译好的插件在目录CMAKE_INSTALL_PREFIX/lib/plugin下&#xff08;默认是/usr/local/mysql/lib/plugin&#xff09;。例如这里编译是指定CMAKE_INSTALL_PREFIX为/home/mysql/mysql&#xff0c;则有&…

Windows7/10上配置OpenCV3.3.0-Python3.6.2操作步骤

目前OpenCV无论是2.4.x还是最新的3.3.0版本&#xff0c;默认支持的都是Python 2.7版本。这里介绍下如何使OpenCV 3.3.0支持Python 3.6.2的操作步骤&#xff1a;1. 从 https://github.com/opencv/opencv/releases/tag/3.3.0 下载3.3.0.zip或opencv-3.3.0-vc14.exe&#xff0c;…

manage.py命令

一、manage.py命令选 manage.py是每个Django项目中自动生成的一个用于管理项目的脚本文件&#xff0c;需要通过python命令执行。manage.py接受的是Django提供的内置命令。 内置命令包含 checkdbshelldiffsettingsflushmakemigrationsmigraterunservershellstartappstartproject…

图灵奖得主Bengio再次警示:可解释因果关系是深度学习发展的当务之急

&#xff08;图片付费下载自视觉中国&#xff09;作者 | Will Knight译者 | Monanfei来源 | Wired出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;深度学习擅长在大量数据中寻找模式&#xff0c;但无法解释它们之间的关系。图灵奖获得者 Yoshua Bengio 希望改变这一状…

解决jQuery不同版同时引用的冲突

今天研发的同事在开发一个新jQuery插件时&#xff0c;遇到一个揪心的问题。平台以前使用的 jQuery版本是1.2.6&#xff0c;偶&#xff0c;天啊&#xff01;这是古代的版本啊&#xff01; 由于很多功能基于老版本&#xff0c;不能删除啊&#xff0c;同志们都懂的&#xff01; 于…

TensorFlow中的计算图

作者 | stephenDC来源 | 大数据与人工智能&#xff08;ID:ai-big-data&#xff09;1 什么是计算图&#xff1f;一个机器学习任务的核心是模型的定义以及模型的参数求解方式&#xff0c;对这两者进行抽象之后&#xff0c;可以确定一个唯一的计算逻辑&#xff0c;将这个逻辑用图表…

java设计模式-适配器模式

模式导读: 每个人都有自己不同的需要&#xff0c;每个人都有自己能够接受的不同方式&#xff0c;就像是为满足现在快速度发展的社会&#xff0c;几乎人人离不开手机的时代&#xff0c;我们也许会碰到在外出行手机电量不足的情况&#xff0c;这个时候如果你在车站&#xff0c;你…

Ubuntu 14.04 64位上安装Valgrind 3.13.0 操作步骤

关于Valgrind的介绍和使用可以参考&#xff1a; http://blog.csdn.net/fengbingchun/article/details/50196189 在Ubuntu 14.04上可以通过以下命令直接安装Valgrind&#xff0c;直接通过命令安装的版本是3.10.1&#xff0c;如下图&#xff0c;有些较老&#xff0c;目前最新版本…