Используйте boost phoenix lambda с io_service
Я использую boost io_service для асинхронного запуска методов:
void my_class::completion_handler()
{
...
}
m_io_service.post(boost::bind(&my_class::completion_handler, this));
Я хотел бы использовать лямбда-выражение вместо boost::bind (см. Ниже), чтобы избежать создания метода для каждого обработчика, но я использую компилятор C++, который не полностью поддерживает C++11:
m_io_service.post([this](){ ... });
Можно ли вести себя так же, используя Phoenix Lambda?
Спасибо.
1 ответ
Да, это возможно.
Наиболее заметное отличие - это заполнители (не используйте std::place_holders::_1
, _2
... но boost::phoenix::arg_names::arg1
, arg2
...).
Тем не менее, просто заменив boost::bind
с std::bind
, boost::lambda::bind
или же boost::phoenix::bind
в конечном счете бесполезно, конечно.
Вместо этого вы могли бы использовать актеров Феникса для создания "лямбд", как, например,
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);
В этом отношении вызовы членов являются хитрыми.
Хорошей новостью является то, что Phoenix поставляется с реализациями многих операций STL, таких как size()
, empty()
, push_back()
и т.п.
Аналогичное использование Phoenix в этой реализации очереди: Boost group_threads Максимальное количество параллельных потоков и, например, проблема жизненного цикла asio::io_service и thread_group).
boost::fusion::function<>
Вы можете адаптировать бесплатные функции с BOOST_PHOENIX_ADAPT_FUNCTION
и функциональные объекты с BOOST_PHOENIX_ADAPT_CALLABLE
, Однако в последнем случае это, вероятно, более элегантно использовать 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_;
};