copy

STL库中的copy函数

template <class InputIterator, class OutputIterator>
  OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result);

常规用法:

int myints[] = {10,20,30,40,50,60,70};
vector<int> myvec(7); //这里需要指定vector的长度

copy(myints,myints+7,myvec.begin());

但是如果我们希望这个赋值是插入复制呢?例如:

原数组1:1,2,3,4,5,6
原数组2:10,20,30,40,50,60
插入复制后的数组:10,20,30,1,2,3,4,5,6,40,50,60

那么使用copy如何实现这样的效果呢?

答案是使用库自带的inserter函数。

vector<int> foo, bar;
for(int i=0;i<=5;i++)
{
    foo.push_back(i);
    bar.push_back(i*10);
}
auto itor = foo.begin();
advance(itor,3); //如果容器是list,那么需要使用advance

//auto itor = foo.begin(); C++11以后已经支持这样的操作了

copy(bar.begin(),bar.end(),inserter(foo,itor));

这样就实现了插入复制操作。

inserter的定义如下:

template <class Container, class Iterator>
  insert_iterator<Container> inserter (Container& x, Iterator it);

可见它返回的仍然是一个迭代器,但是这个迭代器指向的内存不属于原来的容器,而是另外开劈出来的。这样就引入了一个问题。我们先看一下copy操作的源码和inserter的源码:

template <class InputIterator, class OutputIterator>
  OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result){
 	while(first!=last){
 	*result = *first;
 	++result;++first;
 	} 
 	return result;
 }
 
template <class Container>
class insert_iterator{
protected:
    Container* container; //底层容器
    typename Container::iterator iter;
public:
    //...
    insert_iterator<Container>&
        operator=(const typename Container::value_type value)
    {
        iter = container->insert(iter,value);
        ++iter;
        return *this;
    }
}

copy的操作没什么讲的,主要是inserter的操作。我们先感受下inserter的魅力,首先它的返回值是一个迭代器类型,其次它通过运算符重载,使得copy操作悄无声息地与容器自带的insert操作联系了起来,最终实现插入复制操作。这里的核心是操作符重载。

但是,插入复制操作针对非连续地址空间的容器没什么说的,但是对于连续地址空间的容器,比如vector却并不见得那么友好。原因在于其内部重复调用了insert函数,该函数的内部机理涉及到内存的分配。可以这么理解,每调用一次insert函数,vector容器中insert后面的元素就需要进行一次移动,当插入的元素过多,还需要整体搬迁。因此,从效率上讲,这种方式是比较低下的。

更好的方法是,直接使用vector自带的insert函数就支持插入复制

iterator insert (iterator position, const value_type& val);
/* ------------------------------------------------------*/	
void insert (iterator position, size_type n, const value_type& val);
/* ------------------------------------------------------*/	
template <class InputIterator>
    void insert (iterator position, InputIterator first, InputIterator last);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值