2011-09-12 17 views
24

का उपयोग करके, परिणामी बाध्य वस्तु अपेक्षाओं से अधिक तर्क प्राप्त कर सकता है। सैद्धांतिक रूप:बूस्ट :: बाइंड का उपयोग कर सुरक्षित सुरक्षित से अधिक तर्क पारित करने के लिए है?

int func() { return 42; } 
boost::function<int (int,int,int)> boundFunc = boost::bind(&func); 
int answer = boundFunc(1,2,3); 

इस मामले में, func() भले ही उसके हस्ताक्षर इंगित करता है कि यह कोई तर्क लेता स्टैक पर 1,2, और 3 प्राप्त करता है।

यह partial application, जहां मूल्यों एक boost::function कि कम तर्क लेता है लेकिन जब बाध्य वस्तु लागू तर्क की सही संख्या की आपूर्ति उपज कुछ वस्तुओं के लिए निर्धारित कर रहे हैं के लिए boost::bind की खासियत उपयोग से अलग है।

निम्न कोड MSVC++ 2010 SP1 दोनों के साथ काम करता है। यह पोस्ट करने के लिए एक कम रूप है; मूल कोड भी लिनक्स पर जी ++ 4.4 के तहत काम करता है।

क्या सी ++ मानक के अनुसार निम्नलिखित अच्छी तरह से परिभाषित किया गया है?

#include <iostream> 
#include <boost/bind.hpp> 
#include <boost/function.hpp> 

using namespace std; 

void func1(int x) { std::cout << "func1(" << x << ")\n"; } // end func1() 

void func0() { std::cout << "func0()\n"; } // end func0() 

int main(int argc,char* argv[]) 
{ 
     typedef boost::function<void (int)> OneArgFunc; 
     OneArgFunc oneArg = boost::bind(&func1,_1); 
     // here we bind a function that accepts no arguments 
     OneArgFunc zeroArg = boost::bind(&func0); 
     oneArg(42); 
     // here we invoke a function that takes no arguments 
     // with an argument. 
     zeroArg(42); 

    return 0; 
} // end main() 

मुझे समझ में क्यों zeroArg(42) काम करता है: अप्रयुक्त तर्क दिनचर्या को फोन करके ढेर पर रख दिया और कहा जाता है दिनचर्या से बस तक नहीं पहुँचा है। जब नियमित रूप से लौटाया जाता है, तो कॉलिंग दिनचर्या ढेर को साफ करती है। चूंकि यह स्टैक पर तर्क डालता है, इसलिए यह जानता है कि उन्हें कैसे निकाला जाए।

किसी अन्य आर्किटेक्चर पर जा रहे हैं या कंपाइलर इसे तोड़ देगा? क्या अधिक आक्रामक अनुकूलन इसे तोड़ देगा?


मैं बूस्ट दस्तावेज़ या मानक दस्तावेज़ से या तो एक मजबूत कथन की तलाश में हूं। मैं या तो एक स्पष्ट स्थिति खोजने में सक्षम नहीं हूं।

एक डिबगर का उपयोग करना और विधानसभा और ढेर को देख, यह स्पष्ट है कि func पहला उदाहरण से मूल्यों 1,2, और 3 प्राप्त नहीं होता है: यदि आप उस मोर्चे पर सही हैं। दूसरे उदाहरण में func0 के लिए भी यही सच है। यह कम से कम कार्यान्वयन के लिए सच है जो मैं देख रहा हूं, एमएसवीसी ++ 2010SP1 और जी ++ 4.4/लिनक्स।

संदर्भित बूस्ट प्रलेखन को देखते हुए, यह के रूप में स्पष्ट नहीं है के रूप में मैं चाहूँगा कि यह अतिरिक्त तर्क पारित करने के लिए सुरक्षित है:

bind(f, _2, _1)(x, y);     // f(y, x) 

bind(g, _1, 9, _1)(x);     // g(x, 9, x) 

bind(g, _3, _3, _3)(x, y, z);   // g(z, z, z) 

bind(g, _1, _1, _1)(x, y, z);   // g(x, x, x) 

ध्यान दें कि, पिछले उदाहरण में, समारोह वस्तु द्वारा उत्पादित bind(g, _1, _1, _1) में पहले से परे किसी भी तर्क के संदर्भ नहीं हैं, लेकिन इसका अभी भी एक से अधिक तर्कों के साथ उपयोग किया जा सकता है। किसी भी अतिरिक्त तर्क को चुपचाप अनदेखा कर दिया जाता है, जैसे कि पहले और दूसरे तर्क को तीसरे उदाहरण में अनदेखा किया जाता है। [जोर मेरा।]

बयान अतिरिक्त तर्क के बारे में ध्यान नहीं दिया जा के रूप में स्पष्ट रूप में मैं मुझे समझा दिया है कि यह सामान्य मामले में सच है चाहते हैं नहीं है। TR1 पर देखकर, यह धारा 3.6.3 से स्पष्ट है कि कॉल करने योग्य ऑब्जेक्टbind से वापस लक्ष्य ऑब्जेक्ट अपेक्षाओं की तुलना में तर्कों की एक अलग संख्या के साथ बुलाया जा सकता है।क्या यह सबसे अच्छी गारंटी उपलब्ध है?

+5

एक आदर्श पहला सवाल के लिए +1। मैं तुमसे थोड़ा प्यार करता हूँ। वास्तव में –

उत्तर

14

हां, यह सुरक्षित और पोर्टेबल – जैसा कि स्पष्ट रूप से the documentation में उल्लिखित है, boost::bind द्वारा लौटाई गई बाइंड-अभिव्यक्ति चुपचाप अतिरिक्त तर्कों को अनदेखा करती है।

यानी, आपकी पहले उदाहरण में, func करता नहीं मूल्यों 1, 2, और 3boundFunc मूल्यों 1, 2, और 3 प्राप्त करता है और उन्हें निहित बाँध अभिव्यक्ति है, जो सुरक्षित रूप से प्राप्त करता है और यहां पर अग्रेषित प्राप्त उन पर ध्यान नहीं है, और फिर func() invokes। इसी तरह, आपके दूसरे उदाहरण में, zeroArg मूल्य 42 प्राप्त करता है और निहित बाँध अभिव्यक्ति है, जो प्राप्त करता है और मूल्य पर ध्यान नहीं देता और फिर func0() कॉल को फ़ॉरवर्ड पर।

+3

। 'func() 'कॉल स्टैक पर अधिक वस्तुओं को जादुई रूप से प्राप्त नहीं करता है; 'बढ़ावा :: bind' (एक मध्यस्थ के समारोह, वास्तव में) उन्हें स्वीकार करता है (और इसके साथ ठीक है) और फिर बस उन्हें अंतिम कॉल प्राप्त करने वाला के पास भेजने के नहीं है। –

+0

एक डिबगर का उपयोग करना और विधानसभा देख रही है और ढेर, यह स्पष्ट है कि 'पहला उदाहरण से func' मूल्यों 1,2, और 3 प्राप्त नहीं होता है: यदि आप उस मोर्चे पर सही हैं। कम से कम कार्यान्वयन के लिए जो मैं देख रहा हूं, एमएसवीसी ++ 2010SP1 और जी ++ 4.4/लिनक्स। –

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