Reputation: 241
I am using boost io_service to run methods asynchronously:
void my_class::completion_handler()
{
...
}
m_io_service.post(boost::bind(&my_class::completion_handler, this));
I would like to use lambda expression instead of boost::bind (see below) in order to avoid creating method for each handler but I am using a C++ compiler that does not support C++11 fully:
m_io_service.post([this](){ ... });
Is it possible to have the same behavior by using phoenix lambda ?
Thank you.
Upvotes: 1
Views: 229
Reputation: 392911
Yes that's possible.
Most notable difference is the placeholders (don't use std::place_holders::_1
, _2
... but boost::phoenix::arg_names::arg1
, arg2
...).
However, simply replacing boost::bind
with std::bind
, boost::lambda::bind
or boost::phoenix::bind
is ultimately useless of course.
Instead you could use Phoenix actors to compose "lambdas", like e.g.
namespace phx = boost::phoenix;
boost::mutex mx;
boost::condition_variable cv;
boost::unique_lock<boost::mutex> lk(mx);
vc.wait(lk, phx::ref(m_queue_size) > 0);
Member invocations are tricky in that respect.
The good news is that Phoenix comes with implementations of many STL operations like size()
, empty()
, push_back()
etc.
Similar use of Phoenix in this queue implementation: Boost group_threads Maximal number of parallel thread and e.g. asio::io_service and thread_group lifecycle issue).
boost::fusion::function<>
You can adapt free functions with BOOST_PHOENIX_ADAPT_FUNCTION
and function objects with BOOST_PHOENIX_ADAPT_CALLABLE
. However in the latter case it's probably more elegant to use boost::fusion::function<>
:
struct MyType {
MyType()
: complete_(complete_f { this })
{ }
void doSomething() { }
private:
struct complete_f {
MyType* _this;
void operator()() const {
// do something with _this, e.g
this->doSomething();
}
};
boost::phoenix::function<complete_f> complete_;
};
Upvotes: 1