一、迭代器适配器
反向迭代器
插入迭代器
IO流迭代器
其中反向迭代器可以参考以前的文章。
二、插入迭代器
插入迭代器实际上是一个输出迭代器(*it=; ++)
back_insert_iterator
back_inserter
front_insert_iterator
front_inserter
先来看示例:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
8<br>
9<br>
10<br>
11<br>
12<br>
13<br>
14<br>
15<br>
16<br>
17<br>
18<br>
19<br>
20<br>
21<br>
22<br>
23<br>
24<br>
25<br>
26<br>
27<br>
28<br>
29<br>
30<br>
31<br>
32<br>
33<br>
34<br>
35<br>
36<br>
37<br>
38<br></nobr>
|
|
#include<iostream> #include<vector> #include<algorithm>
usingnamespacestd;
voidShowVec(constvector<int>&v)
{ for(vector<int>::const_iteratorit=v.begin();it!=v.end();++it)
{
cout<<*it<<'';
}
cout<<endl;
} intmain(void)
{ inta[]={1,2,3,4,5};
vector<int>v(a,a+5);
vector<int>v2;
back_insert_iterator<vector<int>>bii(v); //*bii=6; bii=6;
ShowVec(v);
back_insert_iterator<vector<int>>bii2(v2);
copy(v.begin(),v.end(),bii2);
ShowVec(v2);
back_inserter(v)=7;
ShowVec(v);
copy(v.begin(),v.end(),back_inserter(v2));
ShowVec(v2);
return0;
}
|
查看back_insert_iterator 类的定义:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
8<br>
9<br>
10<br>
11<br>
12<br>
13<br>
14<br>
15<br>
16<br>
17<br>
18<br>
19<br>
20<br>
21<br>
22<br>
23<br>
24<br>
25<br>
26<br>
27<br>
28<br>
29<br>
30<br>
31<br>
32<br>
33<br>
34<br>
35<br>
36<br>
37<br>
38<br>
39<br>
40<br>
41<br>
42<br>
43<br>
44<br>
45<br>
46<br>
47<br></nobr>
|
|
//TEMPLATECLASSback_insert_iterator template<class_Container> classback_insert_iterator
:public_Outit
{ //wrappushestobackofcontainerasoutputiterator public: typedef_Containercontainer_type; typedeftypename_Container::referencereference;
typedef_Range_checked_iterator_tag_Checked_iterator_category;
explicitback_insert_iterator(_Container&_Cont)
:container(&_Cont)
{ //constructwithcontainer }
back_insert_iterator<_Container>&operator=( typename_Container::const_reference_Val)
{ //pushvalueintocontainer container->push_back(_Val); return(*this);
}
back_insert_iterator<_Container>&operator*()
{ //pretendtoreturndesignatedvalue return(*this);
}
back_insert_iterator<_Container>&operator++()
{ //pretendtopreincrement return(*this);
}
back_insert_iterator<_Container>operator++(int)
{ //pretendtopostincrement return(*this);
}
protected:
_Container*container;//pointertocontainer };
|
类内部的成员container 保存的是指向容器的指针,重载了*, ++, = 等运算符,* 和 ++ 返回的都是迭代器本身,主要看 赋值运算符:
container->push_back(_Val); 即调用了容器的push_back 函数, 所以可以直接写 bii = 6; 即将6压入容器末尾。程序中还调用了copy
函数,回顾copy 源码,主要是以下代码:
for(;_First!=_Last;++_Dest,++_First)
*_Dest=*_First;
其中,_First 和 _Last 分别是v.begin() 和 v.end(), _Dest 是 bii2,上面也说了,*_Dest 返回的是自身,而且++_Dest 返回的也是自
身,从_First 遍历到 _Last ,调用back_insert_iterator 类的operator=,即不断地执行container->push_back(_Val);
容器的元素位置会
自动移动。
再来看back_inserter 函数:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br></nobr>
|
|
//TEMPLATEFUNCTIONback_inserter template<class_Container>inline
back_insert_iterator<_Container>back_inserter(_Container&_Cont)
{ //returnaback_insert_iterator return(std::back_insert_iterator<_Container>(_Cont));
}
|
实际上返回的也是一个back_insert_iterator 对象,所以能直接替换掉bii2。
当然了,与back 配对的就是front,back 是末尾插入,front 是头端插入,需要注意的是front_insert_iterator 的operator= 调用了
push_front 函数,故如vector 是没有实现push_front 的,不能使用front_insert_iterator ,而list 和 deque 是可以使用的。
示例代码如下:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
8<br>
9<br>
10<br>
11<br>
12<br>
13<br>
14<br>
15<br>
16<br>
17<br>
18<br>
19<br>
20<br>
21<br>
22<br>
23<br>
24<br>
25<br>
26<br>
27<br>
28<br>
29<br>
30<br></nobr>
|
|
#include<iostream> #include<vector> #include<list> #include<algorithm>
usingnamespacestd;
voidShowList(constlist<int>&v)
{ for(list<int>::const_iteratorit=v.begin();it!=v.end();++it)
{
cout<<*it<<'';
}
cout<<endl;
}
intmain(void)
{ inta[]={1,2,3,4,5};
list<int>l(a,a+5);
list<int>ll;
front_insert_iterator<list<int>>fii(l);
fii=0;
ShowList(l);
copy(l.begin(),l.end(),front_inserter(ll));
ShowList(ll); return0;
}
|
三、IO流迭代器
输出流迭代器(ostream_iterator)
*it=; ++
输入流迭代器(istream_iterator)
=*it; ->; ++; ==; !=
直接来看示例代码:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
8<br>
9<br>
10<br>
11<br>
12<br>
13<br>
14<br>
15<br>
16<br>
17<br>
18<br>
19<br>
20<br></nobr>
|
|
#include<iostream> #include<vector> #include<list> #include<algorithm>
usingnamespacestd;
intmain(void)
{
vector<int>v;
//copyfromcintovector copy(istream_iterator<int>(cin),istream_iterator<int>(),back_inserter(v));
//copyfromvectortocout copy(v.begin(),v.end(),ostream_iterator<int>(cout,""));
cout<<endl;
return0;
}
|
首先来看istream_iterator 的源码:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
8<br>
9<br>
10<br>
11<br>
12<br>
13<br>
14<br>
15<br>
16<br>
17<br>
18<br>
19<br>
20<br>
21<br>
22<br>
23<br>
24<br>
25<br>
26<br>
27<br>
28<br>
29<br>
30<br>
31<br>
32<br>
33<br>
34<br>
35<br>
36<br>
37<br>
38<br>
39<br>
40<br>
41<br>
42<br>
43<br>
44<br>
45<br>
46<br>
47<br>
48<br>
49<br>
50<br>
51<br>
52<br>
53<br>
54<br>
55<br>
56<br>
57<br>
58<br>
59<br>
60<br>
61<br>
62<br>
63<br>
64<br>
65<br>
66<br></nobr>
|
|
//TEMPLATECLASSistream_iterator template<class_Ty, class_Elem=char, class_Traits=char_traits<_Elem>, class_Diff=ptrdiff_t> classistream_iterator
:publiciterator<input_iterator_tag,_Ty,_Diff, const_Ty*,const_Ty&>
{ //wrap_Tyextractsfrominputstreamasinputiterator typedefistream_iterator<_Ty,_Elem,_Traits,_Diff>_Myt; public: typedef_Elemchar_type; typedef_Traitstraits_type; typedefbasic_istream<_Elem,_Traits>istream_type;
#if_SECURE_SCL typedef_Range_checked_iterator_tag_Checked_iterator_category; #endif
istream_iterator()
:_Myistr(0)
{ //constructsingulariterator }
istream_iterator(istream_type&_Istr)
:_Myistr(&_Istr)
{ //constructwithinputstream _Getval();
}
const_Ty&operator*()const
{ //returndesignatedvalue
return(_Myval);
}
const_Ty*operator->()const
{ //returnpointertoclassobject return(&**this);
}
_Myt&operator++()
{ //preincrement
_Getval(); return(*this);
}
protected: void_Getval()
{ //geta_Tyvalueifpossible if(_Myistr!=0&&!(*_Myistr>>_Myval))
_Myistr=0;
}
istream_type*_Myistr;//pointertoinputstream _Ty_Myval;//lookaheadvalue(validif_Myistrisnotnull) };
|
上面只截取了部分用上的源码,istream_iterator
类有两个成员,一个是输入流对象指针,一个是输入的值,如
istream_iterator<int>(cin)
调用构造函数,初始化_Myistr,且通过函数_Getval() 初始化_Myval,_Getval() 调用输入流的
operator>>
将键盘输入的值赋予_Myval。而istream_iterator<int>()
呢初始化_Myistr 为0,此时_Myval 被忽略。
回顾copy 源码,主要是以下代码:
for(;_First!=_Last;++_Dest,++_First)
*_Dest=*_First;
此时_First 和 _Last 是istream_iterator<int>
类型,_Dest是back_insert_iterator 类型,而判断_First 和 _Last 是否相等,其实
operator != 里面是判断它们的成员指针_Myistr 是否相等,在_Getval 函数可以看到,当我们输入错误(类型不匹配)或者ctrl+z,
则istream_iterator<int>(cin)
的_Myistr 被置为0,此时本来istream_iterator<int>()
的_Myistr 就为0,故相等,不再继续执行下去。
如果不等,即输入正确的话,*First 调用istream_iterator 类的operator* 直接返回_Myval ,接着调用back_insert_iterator
类的
operator=,即调用container 的push_back
,将_Myval 压入容器。++_Dest 是没什么效果的,而++_First 在istream_iterator 类的
operator++
中会继续调用_Getval,即继续获得键盘输入覆盖_Myval。
再来看ostream_iterator 的源码:
C++ Code
<nobr>1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
8<br>
9<br>
10<br>
11<br>
12<br>
13<br>
14<br>
15<br>
16<br>
17<br>
18<br>
19<br>
20<br>
21<br>
22<br>
23<br>
24<br>
25<br>
26<br>
27<br>
28<br>
29<br>
30<br>
31<br>
32<br>
33<br>
34<br>
35<br>
36<br>
37<br>
38<br>
39<br>
40<br>
41<br>
42<br>
43<br>
44<br>
45<br>
46<br></nobr>
|
|
//TEMPLATECLASSostream_iterator template<class_Ty, class_Elem=char, class_Traits=char_traits<_Elem>> classostream_iterator
:public_Outit
{//wrap_Tyinsertstooutputstreamasoutputiterator public: typedef_Elemchar_type; typedef_Traitstraits_type; typedefbasic_ostream<_Elem,_Traits>ostream_type;
#if_SECURE_SCL typedef_Range_checked_iterator_tag_Checked_iterator_category; #endif
ostream_iterator(ostream_type&_Ostr, const_Elem*_Delim=0)
:_Myostr(&_Ostr),_Mydelim(_Delim)
{//constructfromoutputstreamanddelimiter }
ostream_iterator<_Ty,_Elem,_Traits>&operator=(const_Ty&_Val)
{//insertvalueintooutputstream,followedbydelimiter *_Myostr<<_Val; if(_Mydelim!=0)
*_Myostr<<_Mydelim;
return(*this);
}
ostream_iterator<_Ty,_Elem,_Traits>&operator*()
{//pretendtoreturndesignatedvalue return(*this);
}
ostream_iterator<_Ty,_Elem,_Traits>&operator++()
{//pretendtopreincrement return(*this);
}
protected:
const_Elem*_Mydelim;//pointertodelimiterstring(NB:notfreed) ostream_type*_Myostr;//pointertooutputstream };
|
ostream_iterator 类也有两个成员,一个是输出流对象指针,一个是字符串指针,看上面的copy 代码,此时_First 和 _Last
分别是v.begin() 和 v.end(),_Dest是ostream_iterator<int>类型,*_Dest
返回自身,++_Dest 也返回自身,而在operator= 函数中
*_Myostr << _Val;
if (_Mydelim != 0)
*_Myostr << _Mydelim;
即判断如果还有传入字符串,则在输出元素值之后,还伴随着字符串的输出。所以示例代码中的输出是伴随着空格的。
参考:
C++ primer 第四版
Effective C++ 3rd
C++编程规范
分享到:
相关推荐
插入迭代器适配器主要有三种:`insert_iterator`、`front_insert_iterator`和`back_insert_iterator`。 1. `insert_iterator`:这个适配器允许在容器的指定位置插入元素。使用`inserter`函数创建,如`insert_...
### C++ STL迭代器机制剖析 #### 一、引言 在现代软件开发过程中,代码重用是一项重要的技术,能够显著提升开发效率并减少错误。为了实现这一目标,许多编程语言都提供了标准库来帮助开发者复用代码。C++语言中的...
迭代器模式是软件设计模式中的行为模式之一,它在C++编程中有着广泛的应用。这个模式提供了一种方法来顺序访问聚合对象的元素,而无需暴露其底层表示。通过迭代器,用户可以遍历集合中的所有元素,而无需知道如何...
### C++ STL 迭代器 入门 在C++标准模板库(Standard Template Library,简称STL)中,迭代器扮演着极其重要的角色。它不仅简化了对容器元素的操作,还提供了统一的接口来访问容器中的数据。本文将通过轻松幽默的...
总的来说,理解和实现STL迭代器是深入学习C++和STL的关键步骤。通过自定义迭代器,我们可以更好地控制数据的访问和处理,同时也能为自定义容器提供类似STL的标准接口。不过,实际应用中,除非有特殊需求,通常建议...
迭代器有五种类型:输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器,分别对应不同的操作能力和效率。通过迭代器,程序员可以对容器中的元素进行读写操作,而无需了解底层实现细节。 3. **...
STL迭代器类型是C++标准模板库(STL)中的一种基本组件,用于访问和遍历容器中的元素。迭代器提供了一种统一的方式来访问不同的容器类型,并且提供了许多有用的操作,例如读取、写入、移动等。 迭代器类型可以分为...
C++标准库中的迭代器通常提供`begin()`和`end()`函数,分别返回指向聚合开始和结束的迭代器。 3. **迭代器接口**:这是所有迭代器都必须遵循的一组操作,包括初始化、移动到下一个元素、获取当前元素的值以及检查...
根据功能的强弱,C++标准库定义了五种预定义的迭代器: 1. 输入迭代器(InputIterator):只能向前移动,用于读取元素,不可写入。一次只能读取一个元素,无法回溯。 2. 输出迭代器(OutputIterator):只能向前...
### STL迭代器详解 在深入探讨STL(标准模板库)迭代器之前,我们先简要回顾一下STL的核心组成部分:容器、迭代器和算法。STL为C++程序员提供了...理解和掌握STL迭代器的概念和用法,是每个C++程序员必备的技能之一。
`iterator.zip`中的内容很可能是关于STL迭代器使用的示例代码或教程。 迭代器在STL中被设计为一种通用的接口,可以像指针一样操作容器中的元素,但比指针更强大,因为它们具有类型安全性和更多的操作能力。迭代器有...
2. 迭代器:迭代器是STL中的一种设计模式,它像指针一样可以指向容器中的元素,但功能更加强大,支持前向、双向和随机访问。迭代器提供了类似指针的语法,但具有更多操作,如递增、递减、比较和访问元素。 3. 预算...
面向对象方法(STL_analysis)of_Iterator迭代器,这个文档对这进行了详细介绍,供参考!
2. 迭代器:迭代器是STL的灵魂,它像指针一样遍历容器中的元素,但提供了更多操作。理解迭代器的不同类别(输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器)及其使用规则,能帮助编写更健壮的代码...
《iterator_facade》 在C++编程中,迭代器(iterator)是访问容器元素的关键工具,它提供了类似于指针的...理解和使用好`iterator_facade`可以帮助开发者更方便地创建符合STL标准的迭代器,提高代码的可读性和复用性。
它为程序员提供了诸多数据结构的实现,如容器(container)、迭代器(iterator)和算法(algorithm)等,这些组件通过模板类和模板函数实现,以提供高度的代码重用性。STL最初由惠普实验室开发,后被集成进C++标准库中,...
迭代器分为五种类型:输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器。 - **输入迭代器**:只能向前移动,且只支持读取操作。不能修改其指向的值。 示例:`std::istream_iterator` - **输出...
2. **迭代器适配器(Iterator Adapters)**:如`reverse_iterator`可以将正向迭代器转换为反向迭代器,`counting_iterator`用于生成一系列连续整数的迭代器。 3. **智能指针(Smart Pointers)**:虽然不是STL的一...