Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens if I use vector::begin() instead of std::back_inserter(vector) for output of set_intersection?

I have been using the highly concise and intuitive C++ syntax for finding the intersection of two sorted vectors 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));

This should set c to intersection(a,b), assuming a and b are sorted.

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 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.

Anyway, the code with c.begin() compiled under clang.

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?

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.

like image 264
kdog Avatar asked Nov 30 '14 16:11

kdog


People also ask

What does Vector begin () do?

vector::begin() function is a bidirectional iterator used to return an iterator pointing to the first element of the container. vector::end() function is a bidirectional iterator used to return an iterator pointing to the last element of the container.

Why use std:: back_ inserter?

std::back_inserter A back-insert iterator is a special type of output iterator designed to allow algorithms that usually overwrite elements (such as copy ) to instead insert new elements automatically at the end of the container.

How does back_ inserter work in c++?

back_inserter() returns a back_insert_iterator , which has to function like an output iterator. Specifically, it has to support operations such as pre- and post increment, and dereference assignment. If it didn't support those operations, it couldn't be used where output iterators are required.

How do you find the intersection of two vectors in C++?

std::set_intersection in C++ The intersection of two sets is formed only by the elements that are present in both sets. The elements copied by the function come always from the first range, in the same order. The elements in the both the ranges shall already be ordered.


1 Answers

back_inserter inserts the element in the range by calling push_back ( that's why you can't use back_inserter with the range which doesn't provide push_back operation).

So, you won't care about going past the end of the range as push_back automatically expands the container. However, that's not the case with insert using begin().

If you are using begin(), then you have to make sure that destination range is big enough to hold all elements. Failing to do so would instantly transport your code to the realm of undefined behavior.

like image 80
ravi Avatar answered Sep 28 '22 05:09

ravi