Public Group

# c++ set operations

This topic is 2588 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

What is the simplest way to do intersections, unions, etc. of stl sets? As far as I can tell, there is no built in way to do this.

I tried defining my own operators, but it doesn't even work. And this is a needlessly tedious and error prone, and probably inefficient method anyway.

[source lang='cpp']
#include <algorithm>
template <typename T>
inline void operator &= (std::set<T>& a, const std::set<T>& b){
std::set<T> c;
std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), c.begin());
a.swap(c);
}
[/source]

##### Share on other sites
I don't understand what the problem with using std::set_intersection to find the intersection of two sets is. Is it too obfuscated a name?

##### Share on other sites
Well for one thing, the code I posted doesn't compile, and for another thing, I'd prefer to not have to write all those wrapper functions myself. Why isn't there any built in method for doing set intersections?

##### Share on other sites
You need a writable iterator for set_intersection()'s output. Ex:
 std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::inserter(c, c.begin())); 

##### Share on other sites
So is this really the best way to do set intersections?

template <typename T> inline void operator &= (std::set<T>& a, const std::set<T>& b){ decltype(a) c; std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::inserter(c, c.end())); a.swap(c); } template <typename T> inline void operator |= (std::set<T>& a, const std::set<T>& b){ decltype(a) c; std::set_union(a.begin(), a.end(), b.begin(), b.end(), std::inserter(c, c.end())); a.swap(c); } 

##### Share on other sites
Union is probably more efficiently performed by just a.insert(b.begin(), b.end()).

##### Share on other sites
What about operators which create a new set? Should I return it by value or a move reference? I suppose RVO means it doesn't really matter.

template <typename T> inline std::set<T> operator - (const std::set<T>& a, const std::set<T>& b){ std::set<T> c; std::set_difference(a.begin(), a.end(), b.begin(), b.end(), std::inserter(c, c.end())); return c; }

##### Share on other sites
Just return the set. If RVO doesn't kick in move semantics will eliminate most of the overhead anyway.

##### Share on other sites

What about operators which create a new set? Should I return it by value or a move reference? I suppose RVO means it doesn't really matter.

template <typename T> inline std::set<T> operator - (const std::set<T>& a, const std::set<T>& b){ std::set<T> c; std::set_difference(a.begin(), a.end(), b.begin(), b.end(), std::inserter(c, c.end())); return c; }

If you create the set in the function and return it you have no other option then return by value, the set will be gone otherwise when you come to use it later on.Plus you will get a compiler warning stating that you are returing a local variable that can cause sideeffects.

##### Share on other sites
You could return an auto_ptr to the new set, that would take care of deleting it once you'd finished with it.

1. 1
2. 2
3. 3
4. 4
Rutin
15
5. 5

• 13
• 26
• 10
• 11
• 9
• ### Forum Statistics

• Total Topics
633724
• Total Posts
3013554
×