C++ primer读书笔记之iterater

    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;


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值