c ++ 0x lambdas, не позволяя мне передать функцию ptr - PullRequest
5 голосов
/ 29 мая 2011

В настоящее время я пишу программу на C ++ 0x, к которой я довольно новичок.
Я настраиваю обратные вызовы между объектами и использую лямбду для сопоставления типов (как это делает boost::bind())

Если я вызываю функцию в библиотеке asio, например:

 socket_.async_read_some(buffer(&(pBuf->front()), szBuffer),                                                    
     [=](const boost::system::error_code &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: в функции-члене 'void Server :: clientAccepted (std :: shared_ptr, const boost :: system :: error_code &)': Server.cpp: 31: 3: ошибка: нет подходящей функции длявызов 'ClientConnection :: asyncRead (Server :: clientAccepted (std :: shared_ptr, const boost :: system :: error_code &): :)' Server.cpp: 31: 3: примечание: кандидат является: ClientConnection.h: 16:9: примечание: void ClientConnection :: asyncRead (void (*) (std :: string)) ClientConnection.h: 16: 9: примечание: нет kпреобразование для аргумента 1 из 'Server :: clientAccepted (std :: shared_ptr, const boost :: system :: error_code &) ::' to 'void (*) (std :: string)'

Как можно решить эту проблему?

1 Ответ

11 голосов
/ 29 мая 2011

Ваша лямбда неявно захватывает this. Лямбда, которая захватывает вещи, не может преобразоваться в необработанный указатель на функцию.

Итак, вам нужно написать asyncRead, чтобы он непосредственно принимал объект-функцию лямбда, вместо того, чтобы преобразовывать его в указатель на функцию

template<typename CallbackType>
void ClientConnection::asyncRead(CallbackType callback);

В качестве альтернативы, если вы не хотите писать это как шаблон, вы можете использовать полиморфную функцию-обертку для объекта

void ClientConnection::asyncRead(std::function<void(string)> callBack);

Я бы также рассмотрел вопрос об изменении интерфейса обратного вызова, чтобы он принимал строку по константной ссылке (если все реализации обратного вызова по своей сути не хотят изменить или сохранить / переместить переданную строку внутри, что кажется маловероятным в вашем случае).

...