Reputation: 18178
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
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
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