#boost #lambda #bind #boost-asio #c 11
#boost #лямбда #привязка #boost-asio #c 11
Вопрос:
В настоящее время я пишу программу на C 0x, в которой я довольно новичок.
Я настраиваю обратные вызовы между объектами и использую lambda для сопоставления типов (как boost::bind()
это делается разными способами)
Если я вызываю функцию в библиотеке asio, например:
socket_.async_read_some(buffer(amp;(pBuf->front()), szBuffer),
[=](const boost::system::error_code amp;error, size_t byTrans) {
this->doneRead(callBack, pBuf, error, byTrans); });
Это отлично компилируется и выполняется как ожидалось, ‘doneRead’ вызывается обратно из ‘async_read_some’
итак, у меня есть аналогичный обратный вызов в моем собственном коде:
client->asyncRead([=](string msg){this->newMsg(msg); });
Для этого требуется всего лишь строка, а прототип asyncReads выглядит следующим образом
void ClientConnection::asyncRead(void(*callBack)(string))
Но я получаю эту ошибку компиляции:
Server.cpp : В функции-члене ‘аннулирует Server:: clientAccepted(std:: shared_ptr, const boost::system::error_codeamp;)’: Server.cpp:31:3: ошибка: нет соответствующей функции для вызова ‘ClientConnection::AsyncRead(Server:: clientAccepted(std:: shared_ptr, const boost::system::error_codeamp;)::)’ Server.cpp:31:3: примечание: кандидатом является: ClientConnection.h: 16:9: примечание: недействительное ClientConnection::AsyncRead(void (*)(std::string)) ClientConnection.h: 16:9: примечание: не известно преобразование для аргумента 1 из ‘Server:: clientAccepted(std:: shared_ptr, const boost::system::error_codeamp;)::’ в ‘void (*)(std::string)’
Как можно решить эту проблему?
Комментарии:
1. Можете ли вы поделиться сервером:: клиент принят. Похоже, что вы используете предоставленный там обратный вызов, и существует несоответствие между типом лямбда-выражения, которое принимает принятая клиентом функция, и тем, что вы передаете.
Ответ №1:
Ваша лямбда фиксируется this
неявно. Лямбда-выражение, которое фиксирует объекты, не может быть преобразовано в необработанный указатель на функцию.
Итак, вам нужно написать asyncRead
так, чтобы он принимал объект лямбда-функции напрямую, вместо того, чтобы преобразовывать его в указатель на функцию
template<typename CallbackType>
void ClientConnection::asyncRead(CallbackType callback);
В качестве альтернативы, если вы не хотите записывать это как шаблон, вы можете использовать полиморфную функцию object wrapper
void ClientConnection::asyncRead(std::function<void(string)> callBack);
Я бы также рассмотрел возможность изменения интерфейса обратного вызова, чтобы он принимал строку по ссылке const (если только все реализации обратного вызова по своей сути не хотят изменять или сохранять / перемещать переданную строку внутренне, что в вашем случае кажется маловероятным).
Комментарии:
1. итак, я не думаю, что вы знаете, является ли ваш второй способ способом, которым boost делает это? Я пытаюсь таким образом сейчас.
2. да, этот (второй), похоже, понял это, огромное спасибо, брат.