Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use output iterators without a container: Set intersection without storage

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));
}
like image 723
Michaël Avatar asked Dec 03 '25 22:12

Michaël


1 Answers

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.

like image 192
Sebastian Redl Avatar answered Dec 05 '25 13:12

Sebastian Redl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!