2016-01-27 12 views
7

Starając się skompilować to w Visual C++ 2015std :: bind() Błąd: nie można ustalić, które instancja funkcji przeciążonej "boost :: asio :: io_service :: run" ma

auto worker = std::bind(&boost::asio::io_service::run, &(this->service)); 

I otrzymuję błędy:

error C2783: 'std::_Binder<_Ret,_Fx,_Types...> std::bind(_Fx &&,_Types &&...)': could not deduce template argument for '_Ret' 
note: see declaration of 'std::bind' 

error C2783: 'std::_Binder<_Ret,_Fx,_Types...> std::bind(_Fx &&,_Types &&...)': could not deduce template argument for '_Fx' 
note: see declaration of 'std::bind' 

error C2783: 'std::_Binder<std::_Unforced,_Fx,_Types...> std::bind(_Fx &&,_Types &&...)': could not deduce template argument for '_Fx' 
note: see declaration of 'std::bind' 

Dodatkowo IntelliSense narzeka:

cannot determine which instance of overloaded function "boost::asio::io_service::run" is intended 

widzę, że są 2 przeciążenia boost::asio::io_service::run. Ale jak mogę określić, którego użyć?

Z boost::bind: kod kompiluje dobrze:

auto worker = boost::bind(&boost::asio::io_service::run, &(this->service)); 
+2

Po prostu użyj znaku lambda ...> _> – ildjarn

Odpowiedz

6

Od boost::asio::io_service::run ma dwa przeciążeń, trzeba określić, które korzystać podczas używania go jako wskaźnik funkcji (1). To musi być zrobione oddając go do prawej podpisu funkcji:

static_cast<std::size_t(boost::asio::io_service::*)()>(&boost::asio::io_service::run) 

Ponieważ wygląda to straszne, proponuję użyć lambda zamiast wyrażenia wiązania. Wewnątrz lambda, normalna rozdzielczość przeciążenie zachodzi, więc nie ma potrzeby, aby określić przeciążenie extenso:

auto worker = [this]{ return service.run(); }; 

(1) Problem polega na tym, że std::bind wykonuje funkcję nieograniczonego szablonu argumentu , więc reguły odliczania typu szablonu mają zastosowanie zamiast rozdzielczości przeciążenia. C++ nie może określić, jaki powinien być typ _Fx, ponieważ przekazujesz coś, którego typ nie jest określony. Nawet jeśli istnieje taka sztuczka, że ​​C++ może spróbować rozwiązać przeciążenie, gdy używa się faktu, że powiązane argumenty zostaną przekazane do funkcji, zauważ, że w rzeczywistości możliwe są oba przeciążenia: Przeciążenie z boost::system::error_code & ec byłoby po prostu niezwiązane i "curried" zamiast tego (określanie wartości dla tego parametru jest opóźnione do momentu, w którym wywoływane jest worker).

+0

@leemes, Nie przekazujesz kopii obiektu 'this'? – zaratustra

+0

Wiem, ale nie jest gorsze niż przekazanie kopii '& (this-> service)' przez 'bind'. Upewniam się, że 'ten' jest żywy przez cały czas działania io_service. – rustyx

+0

Jeśli 'ten' nie jest objęty ochroną lambda, ale usługa wykonuje (musi), możesz przekazać wskaźnik do usługi według wartości. Z C++ 14: '[s = & (this-> service)] {s-> run(); } 'lub z C++ 11 używając zmiennej tymczasowej przed lambda:' auto s = & (this-> service); auto worker = [s] {s-> run(); }; ' – leemes

Powiązane problemy