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 iterator
public:
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 iterator
iter = container->insert(iter, _Val);
++iter;
return (*this);
}
_Myt& operator=(_Valty&& _Val)
{ // push value into container
iter = container->insert(iter, _STD forward<_Valty>(_Val));
++iter;
return (*this);
}
_Myt& operator*()
{ // pretend to return designated value
return (*this);
}
_Myt& operator++()
{ // pretend to preincrement
return (*this);
}
_Myt& operator++(int)
{ // pretend to postincrement
return (*this);
}
protected:
_Container *container; // pointer to container
typename _Container::iterator iter; // iterator into container
};
发现++运算返回的是自身,怪了,如果是自身,那么就相当于每次都对同一个insert_iterator对象赋值,对怎么能实现自动插入下一个元素呢?
_Myt& operator=(const _Valty& _Val)
{ // insert into container and increment stored iterator
iter = 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;
其实质并不是改变了元素的值,而是增加了两个新元素。