2012-05-11 28 views
62

के बीच अंतर क्या दोनों के बीच कोई अंतर है? या क्या मैं अपने कोड में std::bind द्वारा boost::bind की हर घटना को प्रतिस्थापित करने के लिए सुरक्षित हूं और इस प्रकार बूस्ट पर निर्भरता को हटा देता हूं?सी ++ 11 std :: बाइंड और बूस्ट :: बाइंड

+0

मेरा मानना ​​है कि 'std :: bind' को' बूस्ट :: बाइंड 'से बहुत अधिक कॉपी किया गया था, जब वे सी ++ 11 के साथ बाहर आए, जैसा कि कुछ अन्य चीजों के साथ था। – chris

+9

प्रश्न हालांकि "बहुत ज्यादा" हिस्सा के बारे में है। बूस्ट से उठाए गए कुछ चीजों के साथ, मामूली परिवर्तन किए गए थे। – jalf

उत्तर

84
  • boost::bindhas overloaded relational operators को अद्यतन करने के कोई समस्या नहीं पड़ा है, std::bind नहीं करता है।

  • boost::bindsupports non-default calling conventions, std::bind की गारंटी नहीं है (मानक लाइब्रेरी कार्यान्वयन इसे एक विस्तार के रूप में पेश कर सकता है)।

  • boost::bind एक को नेस्टेड बाँध भाव (boost::protect) की उत्सुक मूल्यांकन को रोकने के लिए अनुमति देने के लिए एक सीधा तंत्र प्रदान करता है, std::bind नहीं करता है। (जिसके अनुसार, एक std::bind साथ boost::protect उपयोग कर सकते हैं अगर वे चाहते हैं, या तुच्छता से अपने दम पर यह reimplement।)

  • std::bind एक करने के लिए एक नेस्टेड बाँध अभिव्यक्ति के रूप में किसी भी उपयोगकर्ता परिभाषित functor के इलाज के लिए अनुमति देने के लिए एक सीधा तंत्र प्रदान करता है बल उत्सुक मूल्यांकन (std::is_bind_expression: [func.bind.isbind]/1, [func.bind.bind]/10), boost::bind नहीं है।

8

मेरे पास पूरा उत्तर नहीं है लेकिन std::bind पैरामीटर सूचियों के बजाय विविध शैक्षिक टेम्पलेट का उपयोग करेगा।

प्लेसहोल्डर्स std::placeholders में std::placeholders::_1 में वैश्विक नामस्थान की बजाय हैं।

मैं नाम स्थान उर्फ ​​

namespace stdph=std::placeholders; 

अलावा साथ stdph है कि मैं करने के लिए सी ++ 11

+0

मौजूदा बूस्ट को पोर्ट करते समय :: बाइंड कोड जो प्लेसहोल्डर्स का उपयोग करते हैं, "नामस्थान std :: प्लेसहोल्डर का उपयोग करके;" फ़ाइल के शीर्ष पर प्लेसहोल्डर्स को वैश्विक नेमस्पेस में डाल दिया जाता है। बेहद सुविधाजनक। – goertzenator

+1

समस्या यह है कि, जब आप पोर्टिंग करते हैं तो आमतौर पर बूस्ट बाइंड के साथ समाप्त होता है, फिर भी इसे झुकाव करता है; किसी भी तरह से और आप मानक के साथ समाप्त होते हैं और प्लेसहोल्डर को बढ़ावा देते हैं। – 111111

+0

यह अनुमान लगाने वाली परियोजना पर निर्भर करता है। मैंने यांत्रिक रूप से अपने सभी बूस्ट फ़ंक्शन को हटा दिया। एचपीपी और बाइंड.एचपीपी में एक सभ्य आकार परियोजना से sed शामिल है और उपरोक्त नामस्थान निर्देश ठीक काम करता है। यदि आपके पास कुछ शीर्षलेख में बाध्य है जो आप नहीं बदल सकते हैं, तो मैं देखता हूं कि चीजें बदसूरत कैसे हो सकती हैं। – goertzenator

16

इसके अलावा ऊपर सूचीबद्ध, को बढ़ावा देने :: बाँध एक महत्वपूर्ण विस्तार बिंदु है: get_pointer() फ़ंक्शन है कि किसी भी स्मार्ट सूचक के साथ बढ़ावा :: बाँध को एकीकृत करने की अनुमति देता है, जैसे। ATL :: CComPtr आदि http://www.boost.org/doc/libs/1_49_0/libs/bind/mem_fn.html#get_pointer

नतीजतन, को बढ़ावा देने के साथ :: बाँध आप भी एक weak_ptr बाध्य कर सकते हैं: http://lists.boost.org/Archives/boost/2012/01/189529.php

+2

'ऑपरेटर *' का समर्थन करने वाले किसी भी स्मार्ट सूचक के साथ मानक कार्यों में 'INVOKE 'कार्यक्षमता –

22

अन्य उत्तर पर उद्धृत कई मतभेद इसके अलावा, यहां दो अन्य अंतर हैं:

  • boost::bind, कुछ स्थितियों में अतिभारित समारोह के नाम से निपटने के लिए है, जबकि std::bind उसी तरह से उन लोगों के साथ सौदा नहीं करता है लगता है। देखें c++11 faq

(जीसीसी 4.7.2 का उपयोग कर, lib संस्करण 1_54 को बढ़ावा देने)

void foo(){} 
void foo(int i){} 

auto badstd1 = std::bind(foo); 
//compile error: no matching function for call to bind(<unresolved overloaded function type>) 
auto badstd2 = std::bind(foo, 1); 
//compile error: no matching function for call to bind(<unresolved overloaded function type>) 
auto std1 = std::bind(static_cast<void(*)()>(foo)); //compiles ok 
auto std2 = std::bind(static_cast<void(*)(int)>(foo), 1); //compiles ok 
auto boost1 = boost::bind(foo, 1); //compiles ok 
auto boost2 = boost::bind(foo); //compiles ok 

तो अगर आप बस std::bind के साथ सभी boost::bind बदल दिया, अपने निर्माण तोड़ सकते थे।

  • std::bind मूल बढ़ावा 1 के रूप में, C++ 11 लैम्ब्डा प्रकार के लिए बाध्य कर सकते हैं जबकि boost::bind।54 को उपयोगकर्ता से इनपुट की आवश्यकता होती है (जब तक return_type परिभाषित नहीं किया जाता है)। देखें boost doc

(जीसीसी 4.7.2 का उपयोग कर, lib संस्करण 1_54 को बढ़ावा देने)

auto fun = [](int i) { return i;}; 
auto stdbound = std::bind(fun, std::placeholders::_1); 
stdbound(1); 

auto boostboundNaive = boost::bind(fun, _1); //compile error. 
// error: no type named ‘result_type’ ... 
auto boostbound1 = boost::bind<int>(fun, _1); //ok 
boostbound1(1); 
auto boostbound2 = boost::bind(boost::type<int>(), fun, _1); //ok 
boostbound2(1); 

तो, अगर आप बस boost::bind के साथ सभी std::bind बदल दिया, अपने निर्माण भी तोड़ सकते थे।