#c #boost-asio #boost-bind
#c #boost-asio #boost-привязка
Вопрос:
Я пишу приложение, которое использует boost::asio
. Asio async_receive
(или async_read
) неизменно отображается с использованием boost::bind
объекта, заданного для обратного вызова:
boost::asio::async_read(socket_,
boost::asio::buffer(read_msg_.data(),
chat_message::header_length),
boost::bind(amp;chat_session::handle_read_header,
shared_from_this(),
boost::asio::placeholders::error));
Это прекрасно, но я бы не хотел воссоздавать объект bind после каждого вызова обратного вызова. Вместо этого я хотел бы создать объект, скажем, в конструкторе моего класса и передать его async_receive .
Проблема в том, что я не знаю, как объявить этот объект в качестве члена класса. Все, что я знаю, это auto, и он, очевидно, не будет работать как член класса.
class Whatever
{
public:
Whatever()
{
functor = boost::bind(amp;Whatever::Callback);
}
private:
void Callback()
{
boost::asio::async_read(socket_,
boost::asio::buffer(read_msg_.data(),
chat_message::header_length),
functor);
}
?? functor; // How do I declare this?
...
};
Примечание: Это вполне может быть преждевременной оптимизацией, но я все равно хотел бы знать, как объявить объект привязки без auto.
Ответ №1:
Используйте boost::function
:
class Whatever
{
public:
Whatever()
{
functor = boost::bind(
amp;chat_session::handle_read_header,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
);
boost::asio::async_read(
socket_,
boost::asio::buffer(
read_msg_.data(),
chat_message::header_length
),
functor
);
}
private:
boost::function<void(const error_code, const size_t)> functor;
};
… или что-то в этом роде.
Комментарии:
1. 1, 🙂 почти, нужен заполнитель для байтов, которые также передаются при привязке — тогда он будет соответствовать вашему объявлению функтора.
Ответ №2:
Я думаю, вы ищете функцию boost.
Вы можете присвоить результат вашего выражения привязки объекту boost::function, если подпись правильная.
Ответ №3:
«Стандартный» способ сделать это — сделать functor
be a std::function
.
Если вы действительно хотите сохранить фактический объект binder, просмотрите сообщения об ошибках компиляции, связанные с binder, чтобы определить точный тип, и попробуйте использовать их для определения фактического типа объекта binder.
Ответ №4:
Возвращаемый тип boost::bind — это boost::function . Вот краткий пример использования очень простой функции:
double f(int i, double d) {
cout << "int = " << i << endl;
return d;
}
boost::function<double (int)> bound_func = boost::bind(f, _1, 1.234);
int i = 99;
cout << bound_func(i) << endl;
В вашем случае функция имеет этот тип:
boost::function<void(const error_code, const size_t)> f;