2016-01-27 3 views
7

Bei dem Versuch, diese in Visual C++ zu kompilieren 2015std :: bind() Fehler: kann nicht die Instanz überladene Funktion "boost :: asio :: io_service :: run" bestimmen soll

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

I‘ m immer Fehler:

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' 

Außerdem klagt IntelliSense mit:

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

ich sehe, dass es 2 Überlastungen von boost::asio::io_service::run. Aber wie kann ich angeben, welche zu verwenden?

Mit boost::bind der Code kompiliert gerade fein:

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

Verwenden Sie einfach ein Lambda ...> _> – ildjarn

Antwort

6

Seit boost::asio::io_service::run zwei Überlastungen hat, müssen Sie angeben, welche zu verwenden, wenn sie als Funktionszeiger (1) verwenden. Dies muss durch Gießen nach rechts Funktion Unterschrift erfolgen:

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

Da diese schrecklich aussieht, schlage ich vor, einen Lambda statt den Binde Ausdruck zu verwenden. Innerhalb einer Lambda, nimmt die normale Überladungsauflösung Platz, so dass Sie brauchen nicht explizit um die Überlastung zu spezifizieren:

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

(1) Das Problem ist, dass std::bind die Funktion durch ein uneingeschränktes Template-Argument , daher gelten die Regeln des Vorlagentypabzugs anstelle der Überladungsauflösung. C++ kann nicht bestimmen, was der Typ _Fx hier sein soll, da Sie etwas übergeben, dessen Typ nicht angegeben ist. Selbst wenn es einen Trick gab, so dass C++ versuchen kann, die Überladung aufzulösen, wenn die Tatsache verwendet wird, dass die gebundenen Argumente an die Funktion übergeben werden, beachten Sie, dass beide Überladungen hier möglich sind: Die Überladung mit boost::system::error_code & ec wäre einfach nicht gebunden und stattdessen "curried" (Angabe des Werts für diesen Parameter wird auf den Zeitpunkt verzögert, zu dem worker aufgerufen wird).

+0

@leemes, übergeben Sie nicht eine Kopie des 'this' Objekts? – zaratustra

+0

Ich weiß, aber es ist nicht schlimmer, als eine Kopie von '& (this-> service)' über 'bind' zu übergeben. Ich stelle sicher, dass 'this 'für die gesamte Dauer des io_service aktiv ist. – rustyx

+0

Wenn 'this' nicht garantiert ist, um das Lambda zu überleben, aber der Dienst (es muss), können Sie einen Zeiger auf den Dienst nach Wert übergeben. Mit C++ 14: '[s = & (this-> service)] {s-> run(); } 'oder mit C++ 11 mit einer temporären Variable vor dem Lambda:' auto s = & (this-> service); auto worker = [s] {s-> run(); }; ' – leemes

Verwandte Themen