(नोट:।जैसा कि पहले ही टैग से स्पष्ट किया जाना चाहिए, इस सख्ती सेसी ++ 03 हैहाँ, मुझे पता है, लैम्ब्डा यह सब दर्द दूर जाना बनाता है (और नए में लाता है प्रकार, मैं शर्त लगाता हूं), लेकिन यह एक एम्बेडेड सिस्टम है, जिसमें 9 0 के ओएस संस्करण के साथ, और मुझे बताया गया है कि मुझे खुशी होनी चाहिए कि मेरे पास सी ++ 03 कंपाइलर (जीसीसी 4.1.एक्स, बीटीडब्लू) है, या सी ++ संकलक बिल्कुल। कृपया सी ++ 11 समाधान पोस्ट करने से दूर रहें। वास्तव में इसे रगड़ने की कोई ज़रूरत नहीं है।
इसके अलावा, std::bind()
, std::function()
इत्यादि वास्तव में std::tr1
में हैं, लेकिन मैंनेसंपादित कियाउपसर्ग, क्योंकि मैंने सोचा था कि यह कोड को अधिकतर शोर जोड़ता है।)std :: bind के साथ यह कैसे करें?
मेरे पास कुछ सर्वर जैसी चीज है जो मुझे कार्यों को पंजीकृत करने की आवश्यकता है और मुझे उन्हें कुछ ऑब्जेक्ट के समान, लेकिन थोड़ा अलग, कॉल करने के लिए अनुकूलित करने की आवश्यकता है। इन कार्यों में अलग-अलग तर्क सूचियां हैं। सर्वर "जानता है" कि जब मैं किसी फ़ंक्शन को पंजीकृत करने का प्रयास करता हूं तो यह केवल सही हस्ताक्षर के साथ स्वीकार करता है (जैसा कि std::function
के रूप में सही है, वह है), टेम्पलेट तर्क के रूप में पारित कुछ जादू टैग के आधार पर।
यहाँ कोड का एक स्केच है:
// this I just use
class server {
public:
template<unsigned int MagicTag>
bool register_call(typename some_traits_type<MagicTag>::func_type);
};
// this needs to be called from the server
class X {
public:
bool foo();
bool bar(std::string&);
bool baz(int);
};
// this is the glue
class Y {
public:
Y(X& x) : x_(x) {
register_call<MAGIC_FOO>(&Y::foo );
register_call<MAGIC_BAZ>(&Y::bar, _1);
register_call<MAGIC_FBZ>(&Y::baz, _1);
}
private:
X& x_;
template<unsigned int MagicTag, typename Function>
bool register_call(Function function) {
somewhere->register_call<MagicTag>(std::bind(function
, this));
}
template<unsigned int MagicTag, typename Function, typename PlaceHolder1>
bool register_call(Function function, PlaceHolder1 place_holder1) {
somewhere->register_call<MagicTag>(std::bind(function
, this
, place_holder1));
}
int foo() {return x_.foo() ? MAGIC_OK : MAGIC_FAILED;}
int bar(std::string& s) {return x_.bar(s) ? MAGIC_OK : MAGIC_FAILED;}
int baz(int i) {return x_.baz(i) ? MAGIC_OK : MAGIC_FAILED;}
};
यह वास्तव में काम करता है, लेकिन वास्तविकता में वहाँ जिस तरह से अधिक कार्य हैं और एक कठिन copy'n'paste प्रयास के रूप में यह कर गरिमा की मेरी भावना का अपमान और सुगंधित कोड पैदा करता है। चूंकि ये सभी फ़ंक्शंस वही कार्य करते हैं, जिसमें केवल वे फंक्शन होते हैं, जिनके पास वे कॉल करते हैं और उनके पास तर्क होते हैं, या पास नहीं होते हैं, इसलिए मुझे std::bind()
के पीछे अंतर छिपाने के लिए उन्हें एक पैरामीट्रिज्ड फ़ंक्शन में फोल्ड करने में सक्षम होना चाहिए। इसे विफल करने के बाद, मैंने पहले किसी भी पैरामीटर के बिना सभी कार्यों के लिए ऐसा किया (जैसे foo()
), जो कि भारी बहुमत है।
int call_it(std::function<bool()> f) {return f() ? MAGIC_OK : MAGIC_FAILED;}
और इसे करने के लिए एक तर्क के रूप X
में उचित समारोह के लिए बाध्य:
तो मैं रूट करने के लिए foo()
की तरह समारोह की सभी कॉल्स X
में एक भी समारोह Y::call_it
कि थकाऊ हिस्सा करता है के माध्यम से चाहता था:
register_call<MAGIC_FOO>(&X::foo); // note the X!
// (this is wrong)
somewhere->register_call<MagicCode>(std::bind(std::bind(&Y::call_it
, this
, function)
, std::ref(x_));
जाहिर है, यह गलत है, और इसलिए इस को हल करने पर मेरे सारे अन्य प्रयास कर रहे हैं। (मैं अब 10 सप्ताह के लिए std::bind()
के साथ खेल रहा हूं, इसलिए कृपया मेरे साथ भालू)। अंत में मैं std::function
के अपरिपक्व गलतियों से उल्लसित त्रुटि संदेशों की अविश्वसनीय भूलभुलैया में खो गया जो एक बड़े आदमी को आँसू में नीचे ला सकता है और कम से कम एक वर्ष के लिए एक संकीर्ण और उसके विस्तारित परिवार को खिलाना चाहिए।
तो इससे पहले कि मैं kill myself out of sheer frustration और अपने बच्चों को अनाथ - मैं यह कैसे कर सकता हूं?
मैंने कभी std :: bind का उपयोग नहीं किया है। एक कबुलीजबाब के लिए यह कैसा है। लेकिन आप नहीं चाहते हैं 'register_call (std :: bind (& y :: call_it, this, std :: bind (ptmf, std :: ref (x_)); '? –
rici
@rici: हां, ज़ाहिर है, तुम सही हो। [मैंने इसे पहले ही देखा है] (http://chat.stackoverflow.com/transcript/10?m=6878122#6878122।) यह बस इतना है कि मैं उस दीवार के खिलाफ अपने सिर को टक्कर लगी है घंटों, और यह काम करने के लिए 1001 वें प्रयास के बीच में भ्रमित स्थिति है, जो मैंने तय किया था कि मुझे इसके बारे में पूछना होगा। समस्या यह है कि मैं इसे दूसरी तरफ काम नहीं कर सकता , या तो। _Sigh._ – sbi
मुझे लगता है कि मैंने कभी std :: bind का उपयोग नहीं किया है। टेम्पलेट मेटाडेबगिंग पागल है। या यह आपको पागल कर देता है। शायद यही कारण है कि सभी मानक लाइब्रेरी कार्यान्वयन घटिया हैं। शुभकामनाएं! – rici