2017-01-30 22 views
0

Могу ли я использовать boost :: bind, чтобы результирующий объект функции сохранял объект, который не объявлен как аргумент связанной целевой функции? Например:Могу ли я использовать boost :: bind для хранения несвязанного объекта?

void Connect(const error_code& errorCode) 
{ 
    ... 
} 

// Invokes Connect after 5 seconds. 
void DelayedConnect() 
{ 
    boost::shared_ptr<boost::asio::deadline_timer> timer = 
     boost::make_shared<boost::asio::deadline_timer>(ioServiceFromSomewhere); 

    timer->expires_from_now(
     boost::posix_time::seconds(5)); 

    // Here I would like to pass the smart pointer 'timer' to the 'bind function object' 
    // so that the deadline_timer is kept alive, even if it is not an actual argument 
    // to 'Connect'. Is this possible with the bind syntax or similar? 
    timer->async_wait(
     boost::bind(&Connect, boost::asio::placeholders::error)); 
} 

пс. Меня больше интересует уже существующий синтаксис этого. Я знаю, что могу сделать собственный код самостоятельно. Я также знаю, что могу сохранить таймер в ручном режиме, но я бы хотел этого избежать.

ответ

2

Да, вы можете сделать это, связывая дополнительные параметры. Я часто делал это с asio, например. чтобы сохранить буферы или другое состояние в ходе асинхронной операции.

Вы также можете получить доступ к этим дополнительные аргументы из обработчика затем, расширив подпись обработчика использовать их:

void Connect(const error_code& errorCode, boost::shared_ptr<asio::deadline_timer> timer) 
{ 
} 

timer.async_wait(
    boost::bind(&Connect, boost::asio::placeholders::error, timer)); 
+0

Спасибо. Это то, что я планирую делать. Есть ли у вас предпочтения в отношении того, какие типы интеллектуальных указателей использовать в таких ситуациях (в области повышения и STL)? –

+0

Я использовал boost :: shared_ptr и std :: shared_ptr. Я думаю, unqiue_ptr тоже может работать, если объект затем перемещается в объект обработчика. Но у меня нет опыта в этом, так как мне все равно нужен shared_ptr. – Matthias247

+0

К сожалению, я получаю ошибки компиляции с компилятором Visual Studio 2012 при использовании дополнительных параметров, как было предложено: ошибка C2039: 'result_type': не является членом ошибки 'global namespace' 'C2208:' boost :: _ bi :: type ': никакие члены, определенные с использованием этого типа ошибка C2825: «F»: должно быть классом или пространством имен, если за ним следует «::» –

1

Да, вы можете просто привязать «слишком много» параметров, и они не будут переданы базовому обработчику. См. Why do objects returned from bind ignore extra arguments?

Это нормально, если только вам не нужно «разговаривать» с объектом таймера с Connect.

PS. Кроме того, не забудьте ожидать завершения таймера с operation_abandoned, когда таймер будет разрушен.

+0

Ok. Думаю, я могу сделать «разговор с», как Matthias247, описанный в предыдущем ответе. Хороший вопрос об операции. –