2012-01-28 21 views
16

में भी किया जाता रहा Boost.Asio दस्तावेज में विभिन्न ट्यूटोरियल कोशिश कर रहा था और C++ 11 लोगों के साथ बढ़ावा घटकों को बदलने के लिए कोशिश की जा। हालांकि, मुझे Timer.5 - Synchronising handlers in multithreaded programs में std :: bind का उपयोग करके त्रुटि मिली।क्यों std नहीं कर सकते :: बाँध और बढ़ावा देने :: बाँध इस Boost.Asio ट्यूटोरियल

#include <iostream> 
#include <boost/asio.hpp> 
#include <boost/thread/thread.hpp> 
#include <boost/bind.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 

class printer { /* Not relevent here */ }; 

int main() 
{ 
    boost::asio::io_service io; 
    printer p(io); 
    boost::thread t(boost::bind(&boost::asio::io_service::run, &io)); 
    io.run(); 
    t.join(); 

    return 0; 
} 

मैं std::bind द्वारा std::thread और boost::bind द्वारा boost::thread को बदलने के लिए करने की कोशिश की: यहाँ कोड प्रस्तावित है।

#include <functional> 
#include <iostream> 
#include <thread> 
#include <boost/asio.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 

class printer { /* Not relevent here */ }; 

int main() { 
    boost::asio::io_service io; 
    printer p(io); 
    std::thread t(std::bind(&boost::asio::io_service::run, &io)); 
    io.run(); 
    t.join(); 
} 

जब जीसीसी 4.7 के साथ संकलन, मैं इस संकलन समय त्रुटि मिली:

g++ -std=c++0x main.cpp -lboost_system -lboost_date_time -lpthread 
main.cpp: In function ‘int main()’: 
main.cpp:52:60: erreur: no matching function for call to ‘bind(<unresolved overloaded function type>, boost::asio::io_service*)’ 
main.cpp:52:60: note: candidates are: 
/usr/include/c++/4.6/functional:1444:5: note: template<class _Functor, class ... _ArgTypes> typename std::_Bind_helper::type std::bind(_Functor&&, _ArgTypes&& ...) 
/usr/include/c++/4.6/functional:1471:5: note: template<class _Result, class _Functor, class ... _ArgTypes> typename std::_Bindres_helper::type std::bind(_Functor&&, _ArgTypes&& ...) 

कहाँ इस त्रुटि से आ रही है, तो खाता है कि मैं किसी भी boost::asio::placeholders का उपयोग नहीं किया को ध्यान में रखकर यहाँ मेरी कोड है (जैसा कि इस stackoverflow प्रश्न Should std::bind be compatible with boost::asio? में समझाया गया है)?

+0

संभावित डुप्लिकेट: http://stackoverflow.com/questions/8924149/should-stdbind-be-compatible-with-boostasio देखें) – mark

+6

चूंकि आप पहले से ही C++ 11 का उपयोग कर रहे हैं: lambdas एक विकल्प हो सकता है आपके लिए 'std :: bind'', उदाहरण के लिए, 'std :: thread t ([& io]() {io.run();});' यह अधिभार संकल्प से पूरी तरह से बचें। – mavam

उत्तर

34

boost::asio::io_service::run() सदस्य समारोह ओवरलोड हो गया है: एक संस्करण एक और संस्करण एक तर्क लेता है, जबकि कोई तर्क लेता है। यही कारण है, boost::asio::io_service::run का का पता लेने के एक संदर्भ में जो संकलक सीधे समारोह के हस्ताक्षर यह मान सकते हैं की आवश्यकता है। हालांकि, std::bind() कटौती जादू करने के लिए है, जबकि ऐसा लगता है कि boost::bind() प्रयास उससे मिलते-जुलते अधिभार अर्थात वह अपने पहले तर्क प्रकार आसानी से सीमित रखना चाहते हैं के लिए लगता है (बढ़ावा उदाहरण मानते हुए वास्तव में संकलित) का पता लगाने की आवश्यकता नहीं है।

इस समस्या के आसपास कार्य आप std::bind() पर पहले तर्क के प्रकार को स्पष्ट रूप से निर्दिष्ट कर सकते हैं (इसे boost::bind() के साथ भी काम करना चाहिए) उदा। इस तरह:

std::bind(static_cast<size_t (boost::asio::io_service::*)()>(&boost::asio::io_service::run), &io); 

मैं जांच न की हो मानक किसी भी आवश्यकताओं व्यक्ति करता है, लेकिन मैं एक कार्यान्वयन जो करता है पर विचार करेगा अगर यह वास्तव में किसी भी आवश्यकताओं नहीं करता है नहीं को तर्क प्रकार निकालना कारनामों के लिए जाना बेहतर गुणवत्ता का हो, हालांकि यह कम काम करता है: यह आवश्यक है कि उपयोगकर्ता कोड लिखता है जो किसी अन्य कंपाइलर पर अपरिवर्तित संकलित कर सकता है।

1

यह एक बहुत बड़ा PITA यह पता लगाने की थी, इसलिए संकेत के लिए आप डिटमार धन्यवाद। बढ़ावा :: बाँध का उपयोग करने वालों के लिए, आप समाधान इस तरह दिखता है:

// create the io_service  

boost::asio::io_service io_service; 

// assign some work to asio before starting 
{ 
    io_service.post(&some_work); // just for example 
    .... 
} 

boost::thread t(boost::bind(static_cast<size_t (boost::asio::io_service::*)()>(&boost::asio::io_service::run), &io_service)); 

// work should be executed in a new thread 

t.join() 

return; 
11

बस एक क्विक नोट, सी ++ lambdas 11 के बाद आप बस का उपयोग कर सकते में सभी faff से बचने और पूरी बात बहुत आसान बनाने के लिए। वर्ष:

boost::thread t(boost::bind(&boost::asio::io_service::run, &io)); 

या std :: संस्करण:

std::thread t(boost::bind(static_cast<size_t (boost::asio::io_service::*)()>(&boost::asio::io_service::run), &io_service)); 

बस बन:

std::thread t([&io_service](){io_service.run();}); 
+2

बस इतना बेहतर है! – UmNyobe

0

Since you're already using C++11: lambdas may be an alternative to std::bind for you, e.g., std::thread t(&io { io.run(); });. This avoid the overload resolution entirely.

सही उत्पादन, समाधान (asio स्टैंडअलोन में प्राप्त करने के लिए या बढ़ावा :: asio) है:

asio::io_service io; 
auto ptrToIoService = &io; 
printer p(io); 

//asio::thread t(std::bind(&asio::io_service::run, &io)); 
//asio::thread t([&io]() {io.run();}); 
asio::thread t([ptrToIoService]() { ptrToIoService->run();}); 

"आइटम 31 के तहत" प्रभावी आधुनिक सी ++ "देखें डिफ़ॉल्ट कैप्चर मोड से बचें।"

संबंधित मुद्दे