Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda as OutputIterator

Tags:

c++

c++11

I come from the Java world and am not too experienced with C++, so the following question has come up. I see that OutputIterator is used quite extensively. What I have seen so far is that people use an inserter, such as std::back_inserter.

Is it not possible to somehow provide a lambda which is called for each element instead of recording the elements in a container?

Example:

Instead of

std::vector<int> my_vector;
set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), std::back_inserter(my_vector));

something like

set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), to_iterator([](int x) {
    std::cout << x;
}));
like image 797
David Frank Avatar asked Oct 13 '15 20:10

David Frank


2 Answers

Boost has function_output_iterator for this purpose:

Live On Coliru

#include <boost/function_output_iterator.hpp>
#include <iostream>
#include <set>

int main() {
    std::set<int> s1{ 1, 2, 3 }, s2{ 3, 4, 5 };
    set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(),
                     boost::make_function_output_iterator([](int x) { std::cout << x; }));
}

Prints:

3

It shouldn't be too hard to write a simplistic version of this (although I'd prefer to use boost::iterator_facade<> myself so you'd still be stuck with boost)

like image 197
sehe Avatar answered Sep 30 '22 04:09

sehe


Is it not possible to somehow provide a lambda which is called for each element instead of recording the elements in a container?

A lambda, by itself, won't be enough as an argument to std::set_intersection. You'll need wrap it in a helper class (functor) that supports the requirements of an OutputIterator.

The crucial operators that an OutputIterator must support are *iter, iter++, and ++iter.

like image 44
R Sahu Avatar answered Sep 30 '22 06:09

R Sahu