分享
 
 
 

介绍一个很好用的overwrite 迭代器

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

介绍一个很好用的overwrite 迭代器

【原标题】C++ Tip#11 Overwrite Iterator

【出处】C++ User Journal December 2002 Volume 20 Number 12

【作者】Ray Virzi

【译者】easyjoy

【关键字】迭代器 容器 拷贝

【摘要】本文介绍了一个新迭代器(overwrite_iterator),可以在不清除容器原有元素的情况下,很方便的直接覆盖拷贝来自某个序列的新元素;并根据需要自动增长容器的大小。

【正文】

如果你要把一个序列(sequence)拷贝到一个容器(container)中去,通常你用std::copy算法,代码如下:

std::copy(start, end, std::back_inserter(container));

这里,start和end是输入序列(假设有N各元素)的迭代器(iterator),container是一个容器,该容器的接口包含函数push_back。假设container开始是空的,那么copy完毕后它就包含N个元素,并且顺序与原来队列中的元素顺序一样。标准库提供的back_inserter模板函数很方便,因为它为container返回一个back_insert_iterator迭代器,这样,复制的元素都被追加到container的末尾了。

现在假设container开始非空(例如:container必须在循环中反复被使用好几次)。那么,要达到原来的目标,必须先调用clear函数然后才能插入新序列。这会导致旧的元素对象被析构,新添加进来的被构造。不仅如此,container自身使用的动态内存也会被释放然后又创建,就像list,map,set的节点。某些vector的实现在调用clear的时候甚至会释放所有内存。通常,考虑到在一个已有的元素上直接copy覆盖更高效。也许你会这样做:

std::copy(start, end, container.begin());

在这里你在container的头部执行了copy-over(覆盖赋值)操作,但是,如果container的大小小于输入序列的长度N的话,这段代码会导致崩溃(crash)。现在需要一个新迭代器,这个新迭代器在到达container的末尾之前执行copy-over操作,之后执行append操作。我给这个迭代器命名为overwrite iterator,其定义见代码清单1;并遵循标准库的惯例,提供两个辅助模板函数(helper template function),来从指定容器构造overwrite iterator,见代码清单2。

现在使用辅助函数,用下面的代码就可以达到我们开始的目的:

std::copy(start, end, overwriter(container));

如果你要从容器的某个迭代器指定位置开始拷贝的话,可以用下面的代码:

std::copy(start, end, overwriter(container, it));

这个copy算法执行结果返回一个overwrite迭代器,指向container中被拷贝的元素的下一个位置。由于这个迭代器有一个到container原来迭代器it的隐式转换(implicit conversion),因此可以很方便的被用来删除容器中剩下的元素(如果有这个需要的话),或者把另外一个序列中的元素复制接着拷贝过来。所以该解决方案式高效的、弹性的、安全的,更重要的是易用的。

【代码清单1】overwrite_iterator的实现

#include <iterator>

template<class Cont>

class overwrite_iterator

: public std::iterator<std::output_iterator_tag, void, void> {

public:

typedef Cont container_type;

typedef Cont::value_type value_type;

explicit overwrite_iterator(Cont& x)

: cont(x), iter(x.begin())

{}

overwrite_iterator(Cont& x, Cont::iterator it)

: cont(x), iter(it)

{}

overwrite_iterator& operator=(const Cont::value_type& val)

{

//iter == cont.end() ? cont.push_back(val) : (*iter = val, ++iter); thx to sky1234

iter == cont.end() ? (cont.push_back(val), iter=cont.end() ): (*iter = val, ++iter);

return *this;

}

overwrite_iterator& operator*()

{

return *this;

}

overwrite_iterator& operator++()

{

return *this;

}

overwrite_iterator operator++(int)

{

return *this;

}

operator Cont::iterator()

{

return iter;

}

protected:

Cont& cont;

Cont::iterator iter;

};

【代码清单2】辅助函数(helper function)

template<class Cont>

overwrite_iterator<Cont> overwriter(Cont& x)

{

return overwrite_iterator<Cont>(x);

}

template<class Cont>

overwrite_iterator<Cont> overwriter(Cont& x, Cont::iterator it)

{

return overwrite_iterator<Cont>(x, it);

}

作者介绍:略。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有