The C++ reference has this example for printing the intersection of two sets (or sorted containers):
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
int main()
{
std::vector<int> v1{7, 2, 3, 4, 5, 6, 7, 8};
std::vector<int> v2{5, 7, 9, 7};
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
std::vector<int> v_intersection;
std::set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(),
std::back_inserter(v_intersection));
for (int n : v_intersection)
std::cout << n << ' ';
std::cout << '\n';
}
In my application, I simply want to iterate through the intersection of two sets; I do not need to store that intersection.
Question: What is the cleanest way to iterate through the intersection of two sets without storing the intersection?
By "cleanest" I mean without re-implementing set_intersection. Here is what I use; this "hacks" the inserter to call a function of my choosing:
#include <stack>
#include <set>
#include <vector>
#include <string>
#include <iostream>
template <typename F>
struct output_function {
using value_type = int;
output_function (F f) : f (f) {}
F f;
void push_back (int x) { f (x); }
};
int main () {
std::vector<int> v1{7, 2, 3, 4, 5, 6, 7, 8};
std::vector<int> v2{5, 7, 9, 7};
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
int z = 0;
auto f = [&z] (int t) { std::cout << z++ << ": " << t << "\n"; };
output_function p (f);
std::set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(),
std::back_inserter (p));
}
If you are willing to use Boost, you can use function_output_iterator.
It's mostly straight-forward to implement yourself, but the logic of having an assignment operator that takes an arbitrary type without hiding the copy assignment operator is a bit annoying.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With