0xbadf00d
0xbadf00d

Reputation: 18178

Iterate over objects which are contained in the intersection of two ranges

Is there something in the standard library which allows me to iterate over objects which are contained in the intersection of two ranges?

In particular, given a function object action, I want to obtain a program which is equivalent to

/* some container supporting a push_back operation */ intersection;
std::set_intersection(first1, last1, first2, last2,
    std::back_inserter(intersection));
for (auto const& element : intersection)
    action(element);

without the need of the insertion into intersection. Sure, it's easy to write such a code, for example

template<class InputIt1, class InputIt2, class UnaryFunction>
void for_each_in_intersection(InputIt1 first1, InputIt1 last1,
    InputIt2 first2, InputIt2 last2, UnaryFunction f)
{
    while (first1 != last1 && first2 != last2)
    {
        if (*first1 < *first2)
            ++first1;
        else
        {
            if (!(*first2 < *first1))
                f(*first1++);
            ++first2;
        }
    }
}

but I hope that there is already something available in the standard library.

Upvotes: 3

Views: 221

Answers (2)

Grisha
Grisha

Reputation: 536

You can use Function Output Iterator from boost:

#include <boost/function_output_iterator.hpp>
#include <vector>
#include <iostream>
#include <algorithm>

int main() {
    std::vector<int> v1 = {1, 2, 3, 4, 5};
    std::vector<int> v2 = {2, 4};
    std::set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(),
            boost::make_function_output_iterator([](int i) {
                std::cout << i * i << '\n';
            }));
}

Upvotes: 6

max66
max66

Reputation: 66200

I don't know nothing in STL that can do what do you want in a way that is better than you codes.

The simpler I can think involves std::for_each(), std::find() std::binary_search() (thanks, Rakete1111) and a lambda function. But I don't think it's a good idea because doesn't use the fact that the containers are ordered the searched values are ordered.

The following is a full working example

#include <vector>
#include <iostream>
#include <algorithm>

template <typename T>
void action (T const & val)
 { std::cout << "- action over " << val << std::endl; }

int main()
 {
   std::vector<int> v1 { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
   std::vector<int> v2 { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };

   std::for_each(v1.cbegin(), v1.cend(),
                 [&](int val) {
      if ( std::binary_search(v2.cbegin(), v2.cend(), val) )
         action(val);
    });
 }

Upvotes: 1

Related Questions