如果我使用vector :: begin()而不是std :: back_inserter(vector)来输出set_intersection会发生什么? [英] What happens if I use vector::begin() instead of std::back_inserter(vector) for output of set_intersection?
问题描述
我一直在使用高度简洁直观的C ++语法来查找两个已排序的向量
的交集,并将结果放在第三个向量中
:
I have been using the highly concise and intuitive C++ syntax for finding the intersection of two sorted vector
s and putting the result in a third vector
:
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
已排序。
This should set c
to intersection(a
,b
), assuming a
and b
are sorted.
但如果我只使用 c.begin()
(我以为我在某个地方看到了一个例子,这就是我做的原因):
But what if I just use c.begin()
(I thought I saw an example somewhere of this, which is why I did):
std::set_intersection(a.begin(),a.end(),b.begin(),b.end(),
c.begin());
set_intersection
预计该参数的OutputIterator
。我认为标准只需要 c.begin()
返回转发迭代器
,我想这可能会也可能不会是 OutputIterator
。
set_intersection
expects an OutputIterator
at that parameter. The standard I believe requires only that c.begin()
return a forward iterator
, which I suppose might or might not be an OutputIterator
.
无论如何,代码 c.begin()
在clang下编译。
Anyway, the code with c.begin()
compiled under clang.
根据标准,保证会发生什么?如果这个编译,可能会发生什么 - 也就是说,当 c.begin()
返回的迭代器最终增加超过向量的末尾时,并且尝试是是为了访问指向的元素,必须/可能发生什么?在这种情况下,符合标准的实现可以无提示地扩展向量,因此 begin()
实际上是附加 OutputIterator
之类的 back_inserter
是吗?
What is guaranteed to happen under the standard? If this compiles, what is likely to happen - that is, when the iterator returned by c.begin()
is eventually incremented past the end of the vector, and an attempt is made to access the element pointed to, what must/may happen? Can a conforming implementation silently extend the vector in this case, so that begin()
is in fact an appending OutputIterator
like back_inserter
is?
我问这主要是为了理解标准如何与迭代器一起工作:真正发生了什么,所以我可以使用STL超越复制和粘贴。
I'm asking this mainly to understand how the standard works with iterators: what's really going on, so I can move beyond copy-and-paste in using the STL.
推荐答案
输出迭代器的重要要求是它是有效且可写的范围
[out,out +
输出大小 )
。
The important requirement for an output iterator is that it be valid and write-able for the range [out, out+
size of output)
.
传递 c.begin()
将导致值覆盖,仅当容器 c
包含足够的要覆盖的元素时才有效。想象一下, c.begin()
返回一个指向大小为0的数组的指针 - 然后在编写 * out ++ = 7时会看到问题。
。
Passing c.begin()
will lead to the values being overwritten which only works if the container c
holds enough elements to overwrite. Imagine that c.begin()
returns a pointer to an array of size 0 - then you'll see the problem when writing *out++ = 7;
.
back_inserter
将每个指定值添加到a vector
(通过 push_back
)并提供一种使STL算法扩展范围的简洁方法 - 它使运算符重载适当地用于迭代器。
back_inserter
adds every assigned value to a vector
(via push_back
) and provides a concise way of making the STL-algorithms extend a range - it overloads the operators that are used for iterators appropriately.
因此
std::set_intersection(a.begin(),a.end(),b.begin(),b.end(),
c.begin());
一旦 set_intersection
写入内容,就会调用未定义的行为它的输出迭代器,也就是说,当 a
和 b
的集合交集不为空时。
invokes undefined behavior once set_intersection
writes something to its output iterator, that is, when the set intersection of a
and b
isn't empty.
在这种情况下,符合标准的实现是否可以静默扩展向量,因此begin()实际上是附加的
OutputIterator
喜欢back_inserter
是吗?
当然。这是未定义的行为。 (这是一种幽默的方式告诉你,你不应该考虑使用它,不管对任何实现的影响。)
Of course. It's undefined behavior. (This is a humorous approach of telling you that you shouldn't even consider using this, no matter the effects on any implementation.)
这篇关于如果我使用vector :: begin()而不是std :: back_inserter(vector)来输出set_intersection会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!