C++ primer读书笔记之iterater

来源:互联网 发布:内涵段子网站源码 编辑:程序博客网 时间:2024/05/19 06:49
    set_intersection(left.begin(), left.end(),                   right.begin(), right.end(),                  inserter(ret_lines, ret_lines.begin()));


求交集,并把产生的结果存入ret_lines。

查阅其函数原型为

template<class InputIterator1, class InputIterator2, class OutputIterator>   OutputIterator set_intersection(      InputIterator1 _First1,       InputIterator1 _Last1,      InputIterator2 _First2,       InputIterator2 _Last2,       OutputIterator _Result   );

表明其返回结果在 _Result 到返回值之间的区间。即认为_Result为结果的begin()迭代器。函数返回值为end()迭代器。于是不明白在那里的inserter(ret_lines,ret_lines.begin())函数的运行机制。inserter是怎么把一个集合一个个地插入到ret_lines中的?查阅文档,发现inserter返回值是insert_iterator.而insert_iterator是一类OutputIterator。

template<class Container>    insert_iterator<Container> inserter(        Container& _Cont,        typename Container::iterator _Where    );

由此猜想,set_intersection算法中,可能存在一种++运算,从begin()一直迭代到end(),从而为区间赋值。这样便可实现insert_iterator的自动循环。查阅源码,果然:

template<class _InIt1,class _InIt2,class _OutIt> inline_OutIt _Set_intersection(_InIt1 _First1, _InIt1 _Last1,_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest){// AND sets [_First1, _Last1) and [_First2, _Last2), using operator<for (; _First1 != _Last1 && _First2 != _Last2; )if (_DEBUG_LT(*_First1, *_First2))++_First1;else if (*_First2 < *_First1)++_First2;else{// copy equivalent*_Dest++ = *_First1++;++_First2;}return (_Dest);}


然后第二个疑惑来了,

*insert_iterator++=*_First1++;在我的意识中,只建了一个insert_iterator,++运算怎么会得到下一个呢?再次查看源码:

template<class _Container>class insert_iterator: public _Outit{// wrap inserts into container as output iteratorpublic:typedef insert_iterator<_Container> _Myt;typedef _Container container_type;typedef typename _Container::const_reference const_reference;typedef typename _Container::value_type _Valty;insert_iterator(_Container& _Cont, typename _Container::iterator _Where): container(&_Cont), iter(_Where){// construct with container and iterator}_Myt& operator=(const _Valty& _Val){// insert into container and increment stored iteratoriter = container->insert(iter, _Val);++iter;return (*this);}_Myt& operator=(_Valty&& _Val){// push value into containeriter = container->insert(iter, _STD forward<_Valty>(_Val));++iter;return (*this);}_Myt& operator*(){// pretend to return designated valuereturn (*this);}_Myt& operator++(){// pretend to preincrementreturn (*this);}_Myt& operator++(int){// pretend to postincrementreturn (*this);}protected:_Container *container;// pointer to containertypename _Container::iterator iter;// iterator into container};


发现++运算返回的是自身,怪了,如果是自身,那么就相当于每次都对同一个insert_iterator对象赋值,对怎么能实现自动插入下一个元素呢?

_Myt& operator=(const _Valty& _Val){// insert into container and increment stored iteratoriter = container->insert(iter, _Val);++iter;return (*this);}


再看对赋值运算符的重载,才发现玄妙在这里,++iter,即每一次对insert_iterator对象赋值,其实是在向目标容易插入一个元素,而非对insert_iterator对象自身有什么影响。因此,可以把insert_iterator看成一个独立的工具类,和容器的元素相互分离,并非我意识中一个元素对应一个迭代器。由此可以推论,对insert_iterator进行两次赋值,即

 

inserter(vec,vec.begin())=1;inserter(vec,vec.begin())=2;


其实质并不是改变了元素的值,而是增加了两个新元素。

原创粉丝点击