user1886318
user1886318

Reputation: 241

Use boost phoenix lambda with io_service

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

Answers (1)

sehe
sehe

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

Related Questions