Suppose I've got a concrete instance C of some class, and a pair of iterators X and Y representing a range [X, Y). I want to do the following: int a, b, c; while (X != Y) { C.foo(*X, a, b, c); ++X; } I can type it out like that, but actually X and Y are zip_iterators, and it's hard for me to figure out how to parameterize the zip_iterator to instantiate it. I tried the following: class EncoderService { boost::asio::io_service work_io_service_; void async_encode(std::vector<const_buffer> inputs, std::vector<mutable_buffer> outputs) { BOOST_ASSERT(s.size() == t.size()); std::for_each( boost::make_zip_iterator(boost::make_tuple(inputs.begin(), outputs.begin())), boost::make_zip_iterator(boost::make_tuple(inputs.end(), outputs.end())), boost::bind( &boost::asio::io_service::post, &work_io_service_, boost::bind( &EncoderService::encode_handler, this))); } void encode_handler(const boost::tuple<const_buffer, mutable_buffer>& buffers) { } }; If I do this I get tons of errors. I'm probably just doing something stupid. Even still the for_each is already complicated and kind of hard to read, I feel like there should be a one or two-liner to do this :( the io_service::post() function simply calls encode_handler() on another thread. I'm thinking it might just be easier to walk each sequence manually, but at some point I was hoping to templatize the async_encode() function rather than have it take vectors.
AMDG Zachary Turner wrote:
std::for_each( boost::make_zip_iterator(boost::make_tuple(inputs.begin(), outputs.begin())), boost::make_zip_iterator(boost::make_tuple(inputs.end(), outputs.end())), boost::bind( &boost::asio::io_service::post, &work_io_service_, boost::bind( &EncoderService::encode_handler, this))); }
Nested binds are treated specially. You need to use boost::protect. However, you're still left with the problem that there's no good way to propagate the zip_iterator value from the outer bind to the inner bind. What you really want is something like this, although it won't quite work, because boost::bind is an overloaded function template boost::bind( &boost::asio::io_service::post, &work_io_service, boost::bind( &boost::bind, &EncoderService::encode_handler, this, _1))
void encode_handler(const boost::tuple<const_buffer, mutable_buffer>& buffers) { }
In Christ, Steven Watanabe
Zachary Turner wrote:
Suppose I've got a concrete instance C of some class, and a pair of iterators X and Y representing a range [X, Y). I want to do the following:
int a, b, c; while (X != Y) { C.foo(*X, a, b, c); ++X; }
I can type it out like that, but actually X and Y are zip_iterators, and it's hard for me to figure out how to parameterize the zip_iterator to instantiate it. I tried the following:
I would try (using boost.iterator and boost.range): BOOST_FOREACH( <value type of iterator> x, boost::make_iterator_range( X, Y ) ) { C.foo( x, a, b, c ); } Perhaps you know the value type of the iterator or you should be able to derive it.
participants (3)
-
John Reid
-
Steven Watanabe
-
Zachary Turner