C++ 中的插入迭代器以及其迭代器适配器

C++ 中有三类迭代器,分别是插入迭代器(inserter),反向迭代器(reverse_iterator)和流迭代器.

这里(vs2003为例)介绍插入迭代器,插入迭代器分别是std::inserter_iterator,std::back_inserter_iterator,std::front_inserter_iterator 三类,对应的迭代器适配器应该是

std::inserter,std::back_inserter,std::front_inserter 。

1. std::inserter_iterator(std::inserter)

  // TEMPLATE FUNCTION inserter
template<class _Container,
 class _Iter> inline
 insert_iterator<_Container> inserter(_Container& _Cont, _Iter _Where)
 { // return insert_iterator
 return (std::insert_iterator<_Container>(_Cont, _Where));
 }
这是是正常的插入迭代器适配器的实现,我们看到函数需要指定容器类型和容器的开始指针(从那个位置开始插入)返回了一个按容器和容器迭代器位置构造出来的迭代器。我们以一个调用例子来说明这个。

std::vector<std::string> v1,v2;
 std::copy(v1.begin(),v1.end(),std::inserter(v2,v2.begin()));

这里表示需要把v1的所有元素插入到v2里面。调用的时序是先构造一个std::inserter 的实例A(命名为A),然后通过 std::copy 里面的循环,不断的调用适配器A的赋值运算符号,将v1 里面的元素赋值给v2。我们来看 std::insert_iterator 的实现,

template<class _Container>
 class insert_iterator
  : public _Outit
 { // wrap inserts into container as output iterator
public:
 typedef _Container container_type;
 typedef typename _Container::reference reference;

 insert_iterator(_Container& _Cont, typename _Container::iterator _Where)
  : container(&_Cont), iter(_Where)
  { // construct with container and iterator
  }

 insert_iterator<_Container>& operator=(
  typename _Container::const_reference _Val)
  { // insert into container and increment stored iterator
  iter = container->insert(iter, _Val);
  ++iter;
  return (*this);

  }

 

//...省略了insert_iterator其他的函数

 

看到

insert_iterator<_Container>& operator=(
  typename _Container::const_reference _Val)
  { // insert into container and increment stored iterator
  iter = container->insert(iter, _Val);
  ++iter;
  return (*this);
  }

 

这里通过传入容器和容器的迭代器,先构造了实例,赋值运算符实际是调用了容器的 container->insert 方法,所以,这里必须需要容器有insert 方法。幸好,几乎所有容器都有insert 方法,所以这个是通用的迭代器。这个insert 方法还必须类似这样声明:

iterator insert(iterator _Where, const _Ty& _Val);

返回一个迭代器,传入位置和值。  

 

2. std::back_inserter_iterator(std::back_inserter)

顾名思义,back_inserter就是在容器的后面插入,实际 back_inserter 的实现和 inserter 基本一样,因为是指定在最后面插入,所以不需要指定插入容易的开始迭代器;

template<class _Container> inline
 back_insert_iterator<_Container> back_inserter(_Container& _Cont)
 { // return a back_insert_iterator
 return (std::back_insert_iterator<_Container>(_Cont));
 }

我们来看  std::back_insert_iterator 的实现,

   // TEMPLATE CLASS back_insert_iterator
template<class _Container>
 class back_insert_iterator
  : public _Outit
 { // wrap pushes to back of container as output iterator
public:
 typedef _Container container_type;
 typedef typename _Container::reference reference;

 explicit back_insert_iterator(_Container& _Cont)
  : container(&_Cont)
  { // construct with container
  }

 back_insert_iterator<_Container>& operator=(
  typename _Container::const_reference _Val)
  { // push value into container
  container->push_back(_Val);
  return (*this);
  }

 

//...省略了back_insert_iterator其他的函数

看到

 back_insert_iterator<_Container>& operator=(
  typename _Container::const_reference _Val)
  { // push value into container
  container->push_back(_Val);
  return (*this);
  }

 

我们同样通过一个调用来看,

 std::vector<std::string> v1,v2;

std::copy(v1.begin(),v1.end(),std::back_inserter(v2));

这里通过传入容器,先构造了实例,赋值运算符实际是调用了容器的 container->push_back 方法,所以,这里必须需要容器有push_back 方法,所以这个对关联容器 std::map,std::muitlmap 就无效了。

 

3. std::front_inserter_iterator(std::front_inserter)

顾名思义,front_inserter 就是在容器的前面插入,实际 front_inserter 的实现和 back_inserter 基本一样,因为是指定在最前面插入,所以不需要指定插入容易的开始迭代器;
// TEMPLATE FUNCTION front_inserter
template<class _Container> inline
 front_insert_iterator<_Container> front_inserter(_Container& _Cont)
 { // return front_insert_iterator
 return (std::front_insert_iterator<_Container>(_Cont));
 }

我们来看  std::front_insert_iterator 的实现,
  // TEMPLATE CLASS front_insert_iterator
template<class _Container>
 class front_insert_iterator
  : public _Outit
 { // wrap pushes to front of container as output iterator
public:
 typedef _Container container_type;
 typedef typename _Container::reference reference;

 explicit front_insert_iterator(_Container& _Cont)
  : container(&_Cont)
  { // construct with container
  }

 front_insert_iterator<_Container>& operator=(
  typename _Container::const_reference _Val)
  { // push value into container
  container->push_front(_Val);
  return (*this);
  }

//...省略了front_insert_iterator其他的函数

看到
 front_insert_iterator<_Container>& operator=(
  typename _Container::const_reference _Val)
  { // push value into container
  container->push_front(_Val);
  return (*this);
  }

 我们同样通过一个调用来看,
 std::vector<std::string> v1,v2;
std::list<std::string> list_1,list_2;
std::copy(v1.begin(),v1.end(),std::front_inserter(list_2));
这里通过传入容器,先构造了实例,赋值运算符实际是调用了容器的 container->push_front 方法,所以,这里就要求容器必须有 push_front 方法,所以这个对关联容器 std::map,std::muitlmap,std::vector 都无效了,
这个对于std::deque,std::queue,std::list 这类有先后顺序的比较有效了。

 

1.4. 总结

总体来说,三类迭代器都是一个输出迭代器,因为他们都继存了 _Outit 输出迭代器。各种对应不同的容器实现,三个迭代器都是利用了operator=() 这个赋值运算符号来实现插入,通过operator*()来取出值。

原文链接: https://www.cnblogs.com/hehehaha/archive/2013/01/28/6333012.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++ 中的插入迭代器以及其迭代器适配器

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/77058

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午5:46
下一篇 2023年2月9日 下午5:46

相关推荐