While trying to get comfortable with boost
, stumbled into problem with using boost::function
along with std::vector
. I'm trying to do a simple thing: have a list of functions with similair signatures and then use all that functions with std::for_each
on sample data. Here is the code:
typedef boost::function<int (const char*)> text_processor;
typedef std::vector<text_processor> text_processors;
text_processors processors;
processors.push_back(std::atoi);
processors.push_back(std::strlen);
const char data[] = "123";
std::for_each(processors.begin(), processors.end(),
std::cout << boost::bind(&text_processors::value_type::operator(), _1, data)
<< "\n"
);
So, with for_each
I'm trying to write to standard output the result of applying every function to sample data. But it won't compile like this (some long message about missing operator <<
for bind
result).
If I remove stream operators then I'll have compilable, but useless code. The trick is that I want to do function applying and text output in single for_each
. What am I missing? Thought it should be easy with lambdas or smth like that, but can't figure out the correct solution.
The problem with your code is that you are trying to create a functor in place in a way that is not allowed (you cannot just throw code at the third argument of for_each
, you need to pass a functor).
Without lambda support in the compiler you can use std::transform
rather than std::for_each
(not tested... but this should work):
std::transform( processors.begin(), processors.end(),
std::ostream_iterator<int>( std::cout, "\n" ),
bind( &text_processors::value_type::operator(), _1, data ) );
If your compiler supports lambdas you can do with it:
const char data[] = "123";
std::for_each(processors.begin(), processors.end(),
[&data]( text_processors const & ) {
std::cout << boost::bind(&text_processors::value_type::operator(), _1, data)
<< "\n"
}
);
But then you can avoid the bind
altogether:
std::for_each( processors.begin(), processors.end(),
[&data]( text_processors::value_type & op ) {
std::cout << op( data ) << "\n";
}
);