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绑定了容器对象x。list与deque容器都具有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_iterator back_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_iterator reverse_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; } |
|