vector<bar> a,b,c; //... std::set_intersection(a.begin(),a.end(),b.begin(),b.end(),std::back_inserter(c));
这应该将c设置为交点(a,b),假设a和b被排序.
但是如果我只是使用c.begin()(我以为我在这里看到一个例子,那就是为什么我这样做)
std::set_intersection(a.begin(),c.begin());
set_intersection需要该参数的OutputIterator.我认为标准只需要c.begin()返回一个前向迭代器,我认为这可能是或不是一个OutputIterator.
无论如何,代码用c.begin()编译在clang下.
什么保证在标准下发生?如果这个编译,可能会发生什么 – 也就是说,当c.begin()返回的迭代器最终会超过向量的结尾时,并尝试访问指向的元素,那么/可能会发生什么?在这种情况下,一个符合一致的实现会静止地扩展向量,所以begin()实际上是一个像back_inserter这样的附加的OutputIterator呢?
我主要是要了解标准如何与迭代器一起工作:真正发生了什么,所以我可以超越使用STL的复制和粘贴.
解决方法
传递c.begin()将导致覆盖的值只有在容器c拥有足够的元素才能覆盖的情况下才起作用.想象一下,c.begin()返回一个指向大小为0的数组的指针 – 那么你在写* out = 7时会看到这个问题.
back_inserter将每个分配的值添加到向量(通过push_back),并提供使STL算法扩展范围的简明方法 – 它重载用于迭代器的运算符.
从而
std::set_intersection(a.begin(),c.begin());
一旦set_intersection向其输出迭代器写入一些东西,也就是当a和b的设置交集不为空时,将调用未定义的行为.
Can a conforming implementation silently extend the vector in this case,so that begin() is in fact an appending
OutputIterator
likeback_inserter
is?
当然.这是未定义的行为. (这是一个幽默的方式,告诉你,你甚至不应该考虑使用这个,无论对任何实现的影响.)