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

Я пишу приложение, которое использует boost::asio. async_receive (или async_read) у Asio всегда отображается с использованием объекта boost::bind, заданного для обратного вызова:

boost::asio::async_read(socket_,
                        boost::asio::buffer(read_msg_.data(),
                                            chat_message::header_length),
                        boost::bind(&chat_session::handle_read_header,
                                    shared_from_this(),
                                    boost::asio::placeholders::error));

Это прекрасно, но я бы не хотел воссоздавать объект связывания после каждого вызова обратного вызова. Вместо этого я хотел бы создать объект, скажем, в конструкторе моего класса и передать его async_receive.

Проблема в том, что я не знаю, как объявить этот объект в качестве члена класса. Все, что я знаю, это авто, и оно явно не будет работать в классе.

class Whatever
{
public:
    Whatever()
    {
        functor = boost::bind(&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.

Ответы [ 4 ]

11 голосов
/ 13 октября 2011

Используйте boost::function:

class Whatever
{
public:
    Whatever()
    {
        functor = boost::bind(
            &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;
};

... или что-то в этом роде.

0 голосов
/ 13 октября 2011

Возвращаемый тип 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;
0 голосов
/ 13 октября 2011

«Стандартный» способ сделать это состоит в том, чтобы functor был std::function.

Если вы действительно хотите сохранить фактический объект связывателя, посмотрите на сообщения об ошибках компиляции, в которых используется связыватель, чтобы выяснить точный тип, и попробуйте использовать их для определения фактического типа объекта связывателя.

0 голосов
/ 13 октября 2011

Я полагаю, вы ищете функция повышения .
Вы можете присвоить результат вашего выражения связывания объекту boost :: function, если подпись верна.

...