c 0x лямбды, не позволяющие мне передавать как функцию ptr

#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. да, этот (второй), похоже, понял это, огромное спасибо, брат.