`

c++ - c++ iterator revisiting

    博客分类:
  • c++
c++ 
阅读更多

In this post we are going to revist the iterator. In this post we are going to look at the insert iterator, revers interator, iostream iterator (istream_iterator and the ostream_iterator), basically the iterators that you may come across each day.

 

Insert Iterator

 

normally you can do the insert at 1. the front of the container; 2. the end of the container; 3. a location indicated the position of the insertion.

 

you will use front_inserter, back_inserter or inserter for each of the tree insert strategy, they are called the inserator adopter.

 

Let's see some code that show you how to use them respectively.

 

 

/**
* insert_iterator.cpp
*  this is the cpp source file that help to portray the use of iterator in the most common cases, such as inserter;
*/


#include "stdafx.h"

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

using std::vector;
using std::back_inserter;
using std::front_inserter;
using std::inserter;  
using std::unique_copy;
using std::cout;
using std::list;


/**
* this is a wrong use of iterator, which may cause the runtime error, because it is highly likely the container.begin() does not point to a valid insert location
*/
int test_runtime_error() { 
	int ia[] = { 0, 1, 1, 2, 3, 5, 5, 8 };
	vector<int> ivec(ia, ia + 8), vres;

	unique_copy(ivec.begin(), ivec.end(), vres.begin());  // this will fail, and more dreadfully it fails on runtime, because the vres may be empty
	return 0;
}

int test_back_inserter()
{
	int ia[] = { 0, 1, 1, 2, 3, 5, 5, 8 };
	vector<int> ivec(ia, ia + 8), vres;

	unique_copy(ivec.begin(), ivec.end(), back_inserter(vres));

	return 0;
}


int test_front_inserter() 
{
	// oops, for a vector you cannot insert to the front, it is not suppported operation for vector
	//int ia[] = { 0, 1, 1, 2, 3, 5, 5, 8 };
	//vector<int> ivec(ia, ia + 8), vres;

	//unique_copy(ivec.begin(), ivec.end(), front_inserter(vres));

	int ia[] = { 0, 1, 1, 2, 3, 5, 5, 8 };
	list<int> ilist (ia, ia + 8), ires;

	unique_copy(ilist.begin(), ilist.end(), front_inserter(ires));
	return 0;
}

int test_inserter()
{
	int ia[] = { 0, 1, 1, 2, 3, 5, 5, 8 };
	vector<int> ivec(ia, ia + 8), vres;

	unique_copy(ivec.begin(), ivec.end(), inserter(vres, vres.begin()));

	return 0;
}

int do_not_trust_this_code()
{
	int ia[] = { 0, 1, 1, 2, 3, 5, 5, 8 };
	vector<int> ivec(ia, ia + 8), vres;

	vector<int>::iterator iter = vres.begin(), iter2 = ivec.begin();

	for (; iter2 != ivec.end(); ++iter, ++iter2) { 
		vres.insert(iter, *iter2);
	}

	return 0;
}



void display(const vector<int> & rvec)
{
	vector<int>::const_iterator it = rvec.begin();
	for (; it != rvec.end(); ++it) {
		cout << *it  << " ";
	}
}

 

 

Reverse Iterators

 

 

begin() and end() returns some kind of forward iterator, where you start from the first element indicated by begin() and end to the element before the end() (exclusive)...

 

While sometimes it make sense to go the other way around where you start from the last element and ends at the first element.

 

 

/* =======================

the following will show  you how to use the reverse iterator, which give you the ability to go over a collection in the reverse ordre

  ======================== */

void reverse_iterator() {
	int ia[] = { 0, 1, 1, 2, 3, 5, 5, 8 };
	vector<int> ivec(ia, ia + 8), vres;

	vector<int>::reverse_iterator r_iter;
	for (r_iter = ivec.rbegin(); // do you see the danger, if a user write the code as ivec.begin(), which return a iter type, then it might fail, but the compile simply does not allow you to do that; you have to call rbegin() or rend()
		r_iter != ivec.rend();
		++r_iter) 
	{
		cout << *r_iter << " ";
		/*
		...
		*/
	}

}
 

 

 

iostream iterator

 

next to discuss is the iostream iterator; Yes, you can treat the io object as the stream and you can think them as a endless sequence of something that you can apply an iterator to walk through. 

 

 

 

below shows an example of using iostream_iterator (by saying iostream_iterator, there are actually two types of iterator, one is the istream_iterator and the other is the ostream_iterator);

 


/* ======================= input : 23 109 4 80 6 34 12 90 34 23 56 23 8 89 23 output: 109 90 56 45 34 23 12 8 6 ======================== */ void iostream_iterator() { istream_iterator <int> input(cin); istream_iterator <int> end_of_stream; // an empty object of istream_iterator is marker of the end of stream vector<int> vec; copy(input, end_of_stream, inserter(vec, vec.begin())); sort (vec.begin(), vec.end(), greater<int>() ); ostream_iterator <int> output (cout); unique_copy(vec.begin(), vec.end(), output); }

 

 

below shows some more examples on how use the ifstream and ofstream and their separately ifstream_iterator and ofstream_iterator; the c++ standard libraries provides the cin and cout operator for you to use ;

 

 

#include <fstream>
#include <string>
using std::string;
using std::ifstream;
using std::ofstream;
using std::endl;
using std::cerr;


void test_ifstream_iterator(){

	ifstream infile ("data1.txt");
	istream_iterator<string> is_string (infile);

    istream_iterator<string> end_of_string;
	vector<string> text;
	copy(is_string, end_of_string, inserter(text, text.begin()));
}


void test_ofstream_iterator() 
{
	// this two lines is irrelevant to our discussion below, but we can still see how to constrct some output stream object
	ofstream outfile("dictionary");
	ostream_iterator<string> os_string(outfile, "\n"); // this is the way how you would provide the necessary sperator in

	// here we are going to read from the standard input and output to the standard output 
	copy(istream_iterator<int>(cin), istream_iterator<int>(), ostream_iterator<int>(cout, ","));

}


int test_fstream_args() 
{
	string file_name;
	cout << "please enter a file to open:  " ;
	cin >> file_name;

	if (file_name.empty() || !cin) {   // this is the c++ way to check if there is valid input or simply because the std input stream is dead
		cerr << "unable to read file name \n"; 
		return -1;
	}
	ifstream infile(file_name.c_str()) ;

		if (! infile) // it has redefined the bool() operator, so you can check in if statement to see if you can read successfully
		{
			cerr << "unable to open " << file_name << endl;
			return -2;   // normally you will return a non-zero value to indicate error
		}

		istream_iterator<string> ins(infile), eos;
		ostream_iterator<string> outs(cout, " ");

		copy(ins, eos, outs);

		return 0;
}
 
分享到:
评论

相关推荐

    c++ 的array源码分析和reverse-iterator和-Array-const-iterator类

    c++ 的array源码分析和reverse-iterator和-Array-const-iterator类

    java-util-iterator.pdf java-util-iterator.pdf

    根据提供的文件信息,本文将深入探讨Java中的`java.util.Iterator`接口及其在集合类中的应用。我们将从以下几个方面进行详细解析: ### 一、集合类的根接口:Collection `Collection`接口是Java集合框架的基础,它...

    Laravel开发-multi-level-array-iterator

    `php-multi-level-array-iterator-master`这个项目很可能包含了完整的实现和示例,你可以下载并研究其代码,以获取更多关于如何在Laravel环境中创建和使用多级数组迭代器的详细信息。 总之,理解并掌握Laravel的...

    开源项目-json-iterator-go.zip

    开源项目“json-iterator-go”是一个针对Go语言的高性能JSON解析库,它的设计目标是提供与标准库`encoding/json`完全兼容的接口,同时在性能上有所提升。这个压缩包`json-iterator-go.zip`包含了项目的源代码,具体...

    前端开源库-async-iterator-all

    `async-iterator-all`是一个非常实用的开源库,专为处理异步迭代器设计,帮助开发者更方便地从异步迭代器中收集所有值并转换成数组。这个库的核心功能是简化了对异步生成器(async generator)的处理,使得异步数据...

    php-file-iterator:FilterIterator实现,该实现基于后缀,前缀和其他排除条件列表来过滤文件

    安装 ... composer require phpunit/php-file-iterator 如果仅在开发过程中需要此库(例如,运行项目的测试套件),则应将其添加为开发时依赖项: composer require --dev phpunit/php-file-iterator

    harmonyos2-lines-async-iterator::left_arrow::right-facing_fist:node.js的懒惰、逐行、文件读取异步迭代器

    与--harmony-async-iterator标志一起使用 可以与 IxJS 一起使用 支持自定义承诺 包括打字稿定义 用法 安装 npm install --save lines-async-iterator # or yarn add lines-async-iterator 示例 1(基本) const ...

    C++-boost库总结.doc

    C++-boost库总结 C++-boost库是C++编程语言的扩展库,提供了大量实用的函数和类,帮助开发者快速高效地开发应用程序。在这里,我们将总结C++-boost库的主要组件和功能。 时间与日期 boost库提供了多种时间和日期...

    Triangular+Triangular-iterator+iterator-overflow.zip

    Triangular类,包含对Triangular类的提领操作Triangular_iterator类,以及异常类iterator_overflow。 输入输出样例为: (3,6) Triangular Series of 6 elements 6 10 15 21 28 36

    开源项目-thrift-iterator-go.zip

    开源项目“thrift-iterator-go.zip”是一个基于Go语言实现的工具,用于解码和编码Thrift消息,而无需依赖Thrift接口定义语言(IDL)。Thrift是一种跨语言的服务开发框架,由Facebook开源,旨在提供高效、轻量级的...

    partition-refinement-iterator:逐步细化有限集的分区

    var iterator = require ( 'partition-refinement-iterator' ) ; var iterate = iterator ( Number ( process . argv [ 2 ] ) ) ; while ( true ) { var n = iterate ( ) ; if ( typeof n == 'undefined' ) break ...

    c++第8单元第3课C++-Test-7-31.rar

    3. **STL(Standard Template Library)**:包括容器(如vector、list、map等)、迭代器(iterator)、算法和函数对象,是C++中极为重要的部分。 4. **命名空间(Namespaces)**:用于避免命名冲突,使代码更易于...

    NX二次开发UF-ATTR-release-user-attribute-iterator 函数介绍

    NX二次开发UF_ATTR_release_user_attribute_iterator 函数介绍,Ufun提供了一系列丰富的 API 函数,可以帮助用户实现自动化、定制化和扩展 NX 软件的功能。无论您是从事机械设计、制造、模具设计、逆向工程、CAE ...

    NX二次开发UF-ATTR-init-user-attribute-iterator 函数介绍

    NX二次开发UF_ATTR_init_user_attribute_iterator 函数介绍,Ufun提供了一系列丰富的 API 函数,可以帮助用户实现自动化、定制化和扩展 NX 软件的功能。无论您是从事机械设计、制造、模具设计、逆向工程、CAE 分析等...

    NX二次开发UF-ATTR-free-user-attribute-iterator-strings 函数介绍

    NX二次开发UF_ATTR_free_user_attribute_iterator_strings 函数介绍,Ufun提供了一系列丰富的 API 函数,可以帮助用户实现自动化、定制化和扩展 NX 软件的功能。无论您是从事机械设计、制造、模具设计、逆向工程、...

    面向对象程序设计英文教学课件:14-Design-Iterator.pptx

    而C++14作为C++的一个版本,进一步提升了语言的效率和灵活性。 在面向对象的程序设计中,集合(Collections)是非常重要的一个部分,特别是当我们需要处理大量数据时。标准模板库(STL)是C++中的一个强大工具,...

    20151910042-刘鹏-DSA思考题-07 - iterator and tree1

    迭代器(Iterator)是软件设计模式中的一个重要概念,它提供了一种方法来顺序访问聚合对象的元素,而不暴露其底层的表示。迭代器允许你遍历一个集合,并按需访问集合中的下一个元素,而无需知道集合的具体实现。迭代...

    rh-nodejs6-nodejs-es6-iterator-2.0.0-5.el7.noarch.rpm

    官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装

Global site tag (gtag.js) - Google Analytics