मैं सदस्य कार्यों को लपेटना चाहता हूं जो एक टेम्पलेट श्रेणी के साथ 'शून्य (क्लासटाइप :: फ़ंक्शन) (ArgType)' प्रकार के अनुरूप हैं। बाद में, मैं इस टेम्पलेट का एक उदाहरण के लिए ClassType का एक उदाहरण पारित करने के लिए चाहते हैं और यह आह्वान लिपटे विधि है: आवरण < की इन्स्टेन्शियशन मेंसी ++ - क्या एक टेम्पलेट में सदस्य फ़ंक्शन प्रकार से वर्ग और तर्क प्रकार निकालना संभव है?
class Foo {
public:
Foo() : f_(0.0) {}
void set(double v) { f_ = v * 2.1; }
double get() { return f_; }
private:
double f_;
};
template <typename ArgType, typename ClassType, void (ClassType::*Method)(ArgType)>
class Wrapper {
public:
explicit Wrapper(ClassType *cls) : cls_(cls) {}
void do_something(ArgType value) {
(cls_->*Method)(value);
}
private:
ClassType *cls_;
};
#include <iostream>
int main(int argc, char ** argv) {
Foo foo;
Wrapper<double, Foo, &Foo::set> wrapper(&foo);
wrapper.do_something(1.0);
std::cout << foo.get() << std::endl;
// outputs "2.1"
return 0;
}
सूचना> कि "फू" दो बार निर्दिष्ट किया जाता है - यह यहाँ अनावश्यक लग रहा है।
तो मैं क्या जानना चाहता हूं कि टेम्पलेट पैरामीटर क्लासटाइप से बचना संभव है या नहीं। उदाहरण के लिए, यदि सदस्य फ़ंक्शन पॉइंटर पैरामीटर से इसे लागू या निकालना संभव है, तो उसे रैपर <> के तत्काल में स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता नहीं होगी।
इसी प्रकार, यह ArgType को स्पष्ट रूप से निर्दिष्ट करने से बचने के लिए उपयोगी होगा, जैसा कि (शायद) इसे Foo :: set से निर्धारित किया जा सकता है?
क्या यह सी ++ में संभव है? शायद ये (पूरी तरह विलक्षण) पंक्तियों के साथ कुछ:
template <void (ClassType::*Method)(ArgType)>
class Wrapper2 {
public:
explicit Wrapper(Method::ClassType *cls) : cls_(cls) {}
void do_something(Method::ArgType value) {
(cls_->*Method)(value);
}
private:
Method::ClassType *cls_;
};
// ...
int main() {
Foo foo;
Wrapper<&Foo::set> wrapper(&foo);
// ...
}
या, शायद लागू किया जा सकता है कि यह है कि इन पंक्तियों के साथ कुछ करना चाहते हैं टेम्पलेट जादू का एक और स्तर नहीं है:
Wrapper<Magic<&Foo::set> > wrapper(&foo);
मैं करने के लिए इच्छुक हूँ पता है कि कौन सी तंत्र उपलब्ध हो सकती है, यदि कोई हो।
मैं सी ++ 03 को आवश्यकता के रूप में उपयोग कर रहा हूं, सी ++ 11 नहीं, बल्कि यह जानने में भी दिलचस्पी है कि सी ++ 11 क्या पेशकश कर सकता है।
संपादित करें: अधिक जानकारी - मैं ~ 300 सदस्य फ़ंक्शंस (क्लासटाइप से संबंधित सभी, या बहुत समान वर्गों के सेट) को लपेटने के लिए इस तंत्र का उपयोग करना चाहता हूं, लेकिन विचार करने के लिए केवल छह या तो हस्ताक्षर होंगे:
- शून्य (ClassType :: समारोह) (ArgType) - जहां ArgType 'चल' है
- शून्य (ClassType :: समारोह) (ArgType) - जहां ArgType 'अभिन्न'
- शून्य है (ClassType :: फंक्शन) (बूल)
- शून्य (क्लासटाइप :: फ़ंक्शन) (इंडेक्स टाइप, ArgType) - उपर्युक्त तीन वाई वें एक अतिरिक्त 'सूचकांक' तर्क
सदस्य कार्यों मैं क्या "properties" एक बड़े विन्यास में कॉल 'संग्रह' वर्ग, उदाहरण के लिए (न कि ऊपर सरल फू से) के लिए 'सेटर' कार्य हैं:
class MyPropertyCollection {
public:
void set_oink(double value) { oink_ = value; }
void set_bar(int value) { bar_ = value; }
void set_squee(bool value) { squee_ = value; }
private:
double oink_;
int bar_;
bool squee_;
};
// elsewhere
WrapperCollection wrapper_collection; // a simple set of wrapper objects, accessed by id
MyPropertyCollection property_collection;
wrapper_collection.add(PROPERTY_OINK_ID, new Wrapper<double, MyPropertySet, &MyPropertySet::set_oink>(&property_collection);
wrapper_collection.add(PROPERTY_BAR_ID, new Wrapper<int, MyPropertySet, &MyPropertySet::set_bar>(&property_collection);
wrapper_collection.add(PROPERTY_SQUEE_ID, new Wrapper<bool, MyPropertySet, &MyPropertySet::set_squee>(&property_collection);
// +300 more
मुझे पूरा यकीन है कि कक्षा वर्गीकरण का उपयोग करना संभव होगा। क्योंकि कटौती रिवर्स में काम करती है, आप आधार टेम्पलेट घोषणा से, विधि टेम्पलेट प्रकार को 3 टेम्पलेट प्रकारों में विस्फोट कर सकते हैं, जिसमें केवल एक ही है। और पोफ, निकाला गया। मैं तुरंत जीसीसी में कोशिश करने जा रहा हूँ। –