STL迭代器技术

来源:互联网 发布:如何解决网络丢包问题 编辑:程序博客网 时间:2024/05/22 16:02
 

STL迭代器技术

C++ STL和各种容已提供了自己的迭代器,如输入迭代器,输出迭代器,前向迭代器,双向迭代器,随机迭代器。但是STL在已有迭代器的基础上,仍然定义了另外一些迭代器,以简化某些情况下的操作。一般在stl_iterator.h文件中提供。

1、输入流迭代器istream_iterator

istream_iterator.h文件中提供。实现了前向迭代操作"++""*"操作。

istream_iterator() : _M_stream(0), _M_ok(false) {}

此构造函数用来构造一个指向流结束位置的迭代器。

istream_iterator(istream_type& s) : _M_stream(&s) { _M_read(); }

将一个输入流对象s与迭代器绑定在一起。

template<class T, class E = char, class T = char_traits<E> >class istream_iterator#include <iterator>#include <fstream>#include <iostream>#include <algorithm>using namespace std;int main(void){//源文件的输入流ifstream rFileStream;rFileStream.open("c:\\1.txt", ios::in);if(!rFileStream){cout << "打开文件失败\n";return 1;}rFileStream >> noskipws; //读入空格//目标文件的输出流ofstream wFileStream;wFileStream.open("c:\\2.txt", ios::out);if(!wFileStream){cout << "打开文件失败\n";return 1;}//copy算法使用输入流迭代器进行文件复制istream_iterator<char>iter_iFile(rFileStream);ostream_iterator<char>iter_oFile(wFileStream);copy(iter_iFile,istream_iterator<char>(), iter_oFile);rFileStream.close();wFileStream.close();return 0;}



2、输出流迭代器ostream_iterator

实现了Output Iterator迭代器要求。提供了前向"++""="操作。"++""*"只是简单地返回*this迭代器自身,它们必须与赋值操作"="结合起来才有意义。

ostream_iterator(ostream_type& s) : _M_stream(&s), _M_string(0) {}

内部绑定一个输出流ostream对象。

ostream_iterator(ostream_type& s, const _CharT* c)

:_M_stream(&s), _M_string(c) { }

用于创建一个使用分隔字符串的输出流迭代器,每次数据写入流,都会把预定字符串c写入流以作做分隔。

template<class T, class E=char, class Tr=char_traits<E> >class ostream_iterator#include <iterator>#include "vector"#include <iostream>#include <algorithm>using namespace std;int main(){vector<int> v;v.push_back(1);v.push_back(23);v.push_back(4);copy(v.begin(),v.end(),ostream_iterator<int>(cout," "));return 1;}


3、向前插入迭代器front_insert_iterator

构架在具有push_front向前插入函数的序列容器上的Output_Iterator迭代器。有"*""++"操作符,需要与"="操作一起使用才有意义。

template<class Cont>

class front_insert_iterator

explicit front_insert_iterator(_Container& x) : container(&x) {

由上可见,使用_Container绑定了容器对象xlistdeque容器都具有push_front函数,可用作绑定的容器。

#include <iterator>#include <deque>#include <iostream>#include <algorithm>using namespace std;int main(void){deque<int> d;d.push_back(12);d.push_back(13);front_insert_iterator<deque<int> > fii(d);*fii++=11;*fii++=10;*fii++=9;copy(d.begin(), d.end(), ostream_iterator<int>(cout, " "));cout << endl;return 0;}


4、向后插入迭代器back_insert_iterator

是一个Output Inerator,架构在push_back函数的容器上,有"*""++"操作符,可用*i++=t

template<class Cont>class back_insert_iteratorback_insert_iterator(_Container& x) : container(&x) { }对容器对象x进行了绑定。Vector,list,deque都有push_back,都可以绑定。#include <iterator>#include <vector>#include <iostream>#include <algorithm>using namespace std;int main(void){int iArray[]={10, 18, 19, 23, 26};int len=sizeof(iArray)/sizeof(int);vector<int> v;v.push_back(2);v.push_back(3);//将数组元素从后插入到vector容器copy(iArray, iArray+len, back_insert_iterator<vector<int> >(v));//打印vector容器元素copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));cout << endl;return 0;}


5、插入迭代器insert_iterator

构架在insert(pos,value)函数的容器上,提供Output Iterator"*""++"操作,可用*i++=t替代insert(i,t)语句,即在i位置前插入元素t。序列容器和有序的关联容器,如vector,list,set,map等都提供有insert函数,都可进行绑定。

template<typename _Container>

class insert_iterator

insert_iterator(_Container& x, typename _Container::iterator i)

: container(&x), iter(i) {}

由上可见,需提供两个参数:绑定的容器对外,还有初始的容器迭代器。其实现如下所示:

operator=(const typename _Container::const_reference value) { iter = container->insert(iter, value);++iter;return *this;}#include <iterator>#include <iostream>#include <set>#include <algorithm>using namespace std; int main(void){int iArray1[5]={3, 9, 10, 13, 16};int iArray2[8]={1, 7, 11, 20, 33, 38, 39, 46};set<int> s;merge(iArray1, iArray1 + 5, iArray2, iArray2 + 8, insert_iterator<set<int> >(s, s.begin()));copy(s.begin(), s.end(), ostream_iterator<int>(cout, " "));cout << endl;return 0;}


6、反向迭代器reverse_iterator

基于随机迭代器构架。有"++""+n""--""-n"操作的迭代方向,与原迭代器相应的迭代操作的方向相反。

template<typename _Iterator>class reverse_iterator explicit reverse_iterator(iterator_type x) : current(x) { }


7、反向双向迭代器reverse_bidirectional_iterator

++”、“--”操作均与原双向迭代器的操作方向相反。内部绑定一个双向迭代器current

template<class BidIt,class T = iterator_traits<BidIt>::value_type,class Ref = T&,class Ptr = T *, class Dist = ptrdiff_t>class reverse_bidirectional_iteratorreverse_bidirectional_iterator();explicit reverse_bidirectional_iterator(BidIt current);注意:这里的*操作实际取的是上一个元素。#include <iterator>#include <list>#include <iostream>#include <algorithm>using namespace std;int main(void){list<int> l;l.push_back(3);l.push_back(9);l.push_back(12);l.push_back(16);l.push_back(20);reverse_bidirectional_iterator<list<int>::iterator, int> rbi_first(l.end());reverse_bidirectional_iterator<list<int>::iterator, int> rbi_end(l.begin());cout << *rbi_first << endl; //打印cout << *++rbi_first << endl; //打印 //cout << *rbi_end << endl; //错误,上一个没有元素。cout << *--rbi_end << endl; //打印return 0;}


8、原始存储迭代器raw_storage_iterator

是用可读写的前向迭代器构造出来,通过*i=t方式取代construct(&*i,t)函数的调用,实现在i所指处生成对象t

template <class _ForwardIterator, class _Tp>class raw_storage_iterator raw_storage_iterator& operator=(const _Tp& element) {_Construct(&*_M_iter, element);//在当前处置所指空间中赋值为对象//element。++操作是进行前向迭代。return *this;} #include <memory>#include <iostream>using namespace std;class A{public:A(int i_):i(i_){}operator int() const { return i; } //转换为int打印private:int i;};int main(void){//分配个对象空间allocator<A> alloc;A* p=alloc.allocate(10); //用原始存储迭代器赋值int i;raw_storage_iterator<A*, A> rsi(p);for(i=0; i<10; i++)*rsi++=A(i);//打印for(i=0; i<10; i++)cout <<static_cast<int>(*p++) << " ";//释放空间alloc.deallocate(p, 10); return 0;}


原创粉丝点击