Как я могу сохранить объект boost ::bind в качестве члена класса?

#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;