कैसे बढ़ावा :: कार्य और बढ़ावा :: काम बाँध


83

मुझे अपने कोड पर मैजिक बॉक्स बिखरे हुए पसंद नहीं हैं ... मूल रूप से किसी फ़ंक्शन को ऑब्जेक्ट में मैप करने की अनुमति देने के लिए ये दो कक्षाएं कैसे काम करती हैं, भले ही फ़ंक्शन <> के पास पूरी तरह से अलग पैरामीटर सेट हो, जो कि एक im पास करने के लिए सेट है boost::bind

यहां तक ​​कि यह विभिन्न कॉलिंग कन्वेंशनों के साथ भी काम करता है (यानी सदस्य विधियां __thiscallवीसी के अधीन हैं , लेकिन "सामान्य" फ़ंक्शन आम तौर पर __cdeclया __stdcallउन लोगों के लिए हैं जिन्हें सी के साथ संगत होने की आवश्यकता है।



1
वास्तव में नहीं - यह प्रश्न बाइंड एंड फंक्शन के बारे में है
1800 सूचना

हाँ और इस प्रकार यह अभी भी इस सवाल को छोड़ देता है कि मैप को कैसे बांध सकते हैं शून्य MyClass: DoSomething (std :: string str, int number) को बढ़ावा देने के लिए :: function <void (int)> बाइंड के माध्यम से (और MyClass :: DoSoething, उदाहरण के लिए, "नमस्ते वर्ल्ड ", _1)
फायर लांसर

2
२०,००० पवित्र गाय का दौरा करता है, इसे बढ़ावा देने वाले पृष्ठ पर होना चाहिए !
unixman83

जवाबों:


96

boost::functionoperator()सही हस्ताक्षर के साथ कुछ भी करने की अनुमति देता है पैरामीटर के रूप में बाध्य किया जा सकता है, और आपके बाइंड के परिणाम को एक पैरामीटर के साथ कहा जा सकता है int, इसलिए इसे बाध्य किया जा सकता है function<void(int)>

यह इस प्रकार काम करता है (यह विवरण समान रूप से लागू होता है std::function):

boost::bind(&klass::member, instance, 0, _1) इस तरह एक वस्तु देता है

struct unspecified_type
{
  ... some members ...
  return_type operator()(int i) const { return instance->*&klass::member(0, i);
}

जहां return_typeऔर intके हस्ताक्षर से घृणा होती है klass::member, और फ़ंक्शन पॉइंटर और बाउंड पैरामीटर वास्तव में ऑब्जेक्ट में संग्रहीत होते हैं, लेकिन यह महत्वपूर्ण नहीं है

अब, boost::functionकिसी भी प्रकार की जाँच नहीं करता है: यह आपके टेम्पलेट पैरामीटर में आपके द्वारा प्रदान की गई कोई भी वस्तु और कोई भी हस्ताक्षर लेगा, और एक ऐसी वस्तु बनाएँ जो आपके हस्ताक्षर के अनुसार कॉल करने योग्य हो और वस्तु को कॉल करे। यदि यह असंभव है, तो यह एक संकलन त्रुटि है।

boost::function वास्तव में इस तरह एक वस्तु है:

template <class Sig>
class function
{
  function_impl<Sig>* f;
public:
  return_type operator()(argument_type arg0) const { return (*f)(arg0); }
};

जहां return_typeऔर argument_typeसे निकाले जाते हैं Sig, और fगतिशील रूप से ढेर पर आवंटित किया जाता है। यह अलग आकार के साथ पूरी तरह से असंबंधित वस्तुओं को अनुमति देने के लिए आवश्यक है boost::function

function_impl सिर्फ एक अमूर्त वर्ग है

template <class Sig>
class function_impl
{
public:
  virtual return_type operator()(argument_type arg0) const=0;
};

वह वर्ग जो सभी कार्य करता है, एक ठोस वर्ग है, जो व्युत्पन्न है boost::function। आपके द्वारा निर्दिष्ट प्रत्येक प्रकार की वस्तु के लिए एक हैboost::function

template <class Sig, class Object>
class function_impl_concrete : public function_impl<Sig>
{
  Object o
public:
  virtual return_type operator()(argument_type arg0) const=0 { return o(arg0); }
};

आपके मामले में इसका मतलब है, कार्य को बढ़ावा देने के लिए असाइनमेंट:

  1. एक प्रकार का तात्कालिकता function_impl_concrete<void(int), unspecified_type>(वह समय संकलन करता है, निश्चित रूप से)
  2. ढेर पर उस प्रकार की एक नई वस्तु बनाता है
  3. बूस्ट के सदस्य :: फ़ंक्शन को यह ऑब्जेक्ट असाइन करता है

जब आप फ़ंक्शन ऑब्जेक्ट को कॉल करते हैं, तो यह इसके कार्यान्वयन ऑब्जेक्ट के वर्चुअल फ़ंक्शन को कॉल करता है, जो कॉल को आपके मूल फ़ंक्शन पर निर्देशित करेगा।

अस्वीकरण: ध्यान दें कि इस विवरण में नाम जानबूझकर बनाए गए हैं। वास्तविक व्यक्तियों या पात्रों से कोई समानता ... आप इसे जानते हैं। उद्देश्य सिद्धांतों को स्पष्ट करना था।


इसलिए संरचना की संरचना अनिर्दिष्ट_पट्टी (अर्थात ऑपरेटर में कोड) फ़ंक्शन को मूल रूप से बढ़ावा देने के लिए तर्कों से उत्पन्न होती है :: किसी भी संयोजन और तर्कों की संख्या की अनुमति देने के लिए केस आधारों द्वारा किसी मामले पर बाध्य करें?
फायर लांसर

1
नहीं, ऑपरेटर के टेम्पलेट हैं () जो सभी
आरतियों को

पिछले कोड ब्लॉक में यह पढ़ता है: arg0) const=0 { return...... मैंने पहले कभी नहीं देखा। मुझे एक मंच में एक गैर-कामकाज का उदाहरण मिला, जहां C ++ faq से जुड़ा एक अनुवर्ती संदेश बताता है कि एक शुद्ध आभासी फ़ंक्शन का एक शरीर हो सकता है, लेकिन मुझे उस तरह के वाक्यविन्यास (clang & gcc) का उपयोग करके संकलन करने के लिए कोई कोड नहीं मिल सकता है।
ब्रायन वंडेनबर्ग

मुझे अपना प्रश्न थोड़ा स्पष्ट करना चाहिए: एक शुद्ध आभासी को एक शरीर दिया जा सकता है जब =0;बाद में दिए गए शरीर के साथ घोषित किया जाता है (जैसे, void Base::Blah() { /* ... */ }) ... मैं विशेष रूप से ऊपर इस्तेमाल किए गए संकेतन के बारे में पूछ रहा हूं; मुझे लगता है कि यह सिर्फ एक टाइपो है।
ब्रायन वंडेनबर्ग

@BrianVandenberg: मुझे लगता है कि यह मानक अनुरूप है, हालांकि काफी व्यर्थ है।
मूइंग डक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.