I have been trying to find the intersection between two std::set in C++, but I keep getting an error.
I created a small sample test for this
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
int main() {
set<int> s1;
set<int> s2;
s1.insert(1);
s1.insert(2);
s1.insert(3);
s1.insert(4);
s2.insert(1);
s2.insert(6);
s2.insert(3);
s2.insert(0);
set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end());
return 0;
}
The latter program does not generate any output, but I expect to have a new set (let's call it s3
) with the following values:
s3 = [ 1 , 3 ]
Instead I'm getting the error:
test.cpp: In function ‘int main()’:
test.cpp:19: error: no matching function for call to ‘set_intersection(std::_Rb_tree_const_iterator<int>, std::_Rb_tree_const_iterator<int>, std::_Rb_tree_const_iterator<int>, std::_Rb_tree_const_iterator<int>)’
What I understand out of this error, is that there's no definition in set_intersection
that accepts Rb_tree_const_iterator<int>
as parameter.
Furthermore, I suppose the std::set.begin()
method returns an object of such type,
is there a better way to find the intersection of two std::set
in C++? Preferably a built-in function?
Thanks a lot!
You havent provided an output iterator for set_intersection
Fix this by doing something like
You need a
std::insert
iterator since the set is as of now empty. We cannot use back_ or front_inserter since set doesnt support those operations.Have a look at the sample in the link: http://en.cppreference.com/w/cpp/algorithm/set_intersection
You need another container to store the intersection data, below code suppose to work:
Just comment here. I think it is time to add union, intersect operation to the set interface. Let's propose this in the future standards. I have been using the std for a long time, each time I used the set operation I wished the std were better. For some complicated set operation, like intersect, you may simply (easier?) modify the following code:
copied from http://www.cplusplus.com/reference/algorithm/set_intersection/
For example, if your output is a set, you can output.insert(*first1). Furthermore, you function may not be templated.If you code can be shorter than using the std set_intersection function then go ahead with it.
If you want to do a union of two set you can simply setA.insert(setB.begin(), setB.end()); This is much simpler than the set_union method. However, this will not work with vector.
The first (well-voted) comment of the accepted answer complains about a missing operator for the existing std set operations.
On one hand, I understand the lack of such operators in the standard library. On the other hand, it is easy to add them (for the personal joy) if desired. I overloaded
operator *()
for intersection of setsoperator +()
for union of sets.Sample
test-set-ops.cc
:Compiled and tested:
What I don't like is the copy of return values in the operators. May be, this could be solved using move assignment but this is still beyond my skills.Due to my limited knowledge about these "new fancy" move semantics, I was concerned about the operator returns which might cause copies of the returned sets. Olaf Dietsche pointed out that these concerns are unnecessary as
std::set
is already equipped with move constructor/assignment.Although I believed him, I was thinking how to check this out (for something like "self-convincing"). Actually, it is quite easy. As templates has to be provided in source code, you can simply step through with the debugger. Thus, I placed a break point right at the
return s;
of theoperator *()
and proceeded with single-step which leaded me immediately intostd::set::set(_myt&& _Right)
: et voilà – the move constructor. Thanks, Olaf, for the (my) enlightment.For the sake of completeness, I implemented the corresponding assignment operators as well
operator *=()
for "destructive" intersection of setsoperator +=()
for "destructive" union of sets.Sample
test-set-assign-ops.cc
:Compiled and tested:
See std::set_intersection. You must add an output iterator, where you will store the result:
See Ideone for full listing.