iCoder.ME

C, C++, Emacs lisp and more…

STL中的insert_iterator和inserter

我在使用STL的set_intersetion函数求两个集合交集时遇到了下面的问题:

// two sets: set<int> s1, s2;
set result;
set_intersetion(s1.begin(), s1.end(), s2.begin(), s2.end(), result.begin());
        // 求集合s1和s2的交集,存入result中
        // ERR: 这里会产生一个运行时错误!

在第3行会有一个运行时错误,因为交集的数据将会插入到result中,而现在result还没有空间。

STL提供了insert_iterator[1][2]来解决这样的问题

所以上面的例子应该写成这样:

set result; // 存结果的集合
insert_iterator< set > result_it(result, result.begin()); // 插入迭代器
set_intersetion(s1.begin(), s1.end(), s2.begin(), s2.end(), result_it); // ok

在STL里还提供了一个对insert_iterator方便的包装:insertor,所以上面的可以简单的改写成:

set result; // 存结果的集合
set_intersetion(s1.begin(), s1.end(), s2.begin(), s2.end(), insertor(result, result.begin())); // ok

类似的类还有back_insert_iteratorfront_insert_iterator.

简单解释下insert_iterator的原理:像set_intersetion这样的函数(比如还有:copy)内部所使用了” = “赋值表达式,而insert_iterator调用了insert函数[2],使得container插入了一个新的空间,这样就保证了前面这些函数不会出错。

注意:因为insert_iterator调用了容器的insert函数,所以具体插入的结果和效率与容器本身有着很大关系(比如list和vector效率就会很大差异),使用时必须小心。

参考文献:
[1] insert_iterator, cplusplus.com: [a]http://www.cplusplus.com/reference/std/iterator/insert_iterator/[/a]
[2] insert_iterator, Stanford University: [a]http://www.stanford.edu/class/cs106l/reference/insert_iterator.html[/a]

Leave a comment