介绍一个很好用的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);
}
作者介绍:略。
本文地址:http://com.8s8s.com/it/it1018.htm