views:

133

answers:

1

Why does this code result in a run-time error "vector iterator not incrementable"?

vector<string> s1, s2;

 s1.push_back("joe");
 s1.push_back("steve");
 s1.push_back("jill");
 s1.push_back("svetlana");

 s2.push_back("bob");
 s2.push_back("james");
 s2.push_back("jill");
 s2.push_back("barbara");
 s2.push_back("steve");

 sort(s1.begin(), s1.end());
 sort(s2.begin(), s2.end());

 vector<string> result;
 vector<string>::iterator it_end, it_begin;
 it_end = set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), result.begin());
 cout << int (it_end - result.begin()) << endl;
 for_each(result.begin(), result.end(), print);

Thanks in advance for your help!

+5  A: 

result.begin() of an empty vector is not a valid output iterator. You need a back_inserter(result) instead.

#include <iterator>
...
set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), back_inserter(result));
cout << result.size() << endl;

Alternatively, resize result to at least 4, so that the vector can contain all results.

KennyTM
Interestingly, this does not compile for me. I use `back_inserter` all the time, and I can't figure out why this isn't working.
John Dibling
Thanks Kenny, that did it.
shaz
Without knowing the error, do you miss the `<iterator>` include?
Mark B
@John: [Works for me](http://www.ideone.com/ekakQ).
KennyTM
How would you modify this to use set instead of vector?
shaz
@Mark: Nope, maybe I'll put up a new post.
John Dibling
Ah, I see what the problem is. OP was trying to assign the results of `set_intersection` to a `vector<string>::iterator`, rather than a `back_insert_iterator<vector<string> >`
John Dibling
And Kenny's solution didn't keep the return value from `set_intersection`
John Dibling
@KennyTM: Additional +1 for the link to ideone.com :)
John Dibling
@myself - replace back_inserter with inserter(set, set.begin()) to put output into a set rather than a vector
shaz