CSDN博客

img easyjoy

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

发表于2004/4/15 16:06:00  662人阅读

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

 

【原标题】C++ Tip11 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));

 

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

 

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

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

 

在这里你在container的头部执行了copyover(覆盖赋值)操作,但是,如果container的大小小于输入序列的长度N的话,这段代码会导致崩溃(crash)。现在需要一个新迭代器,这个新迭代器在到达container的末尾之前执行copyover操作,之后执行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),因此可以很方便的被用来删除容器中剩下的元素(如果有这个需要的话),或者把另外一个序列中的元素复制接着拷贝过来。所以该解决方案式高效的、弹性的、安全的,更重要的是易用的。

 

【代码清单1overwrite_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);

}

  

作者介绍:略。

0 0

相关博文

我的热门文章

img
取 消
img