2008-11-02 6 views
6

मैं अपने आवेदन के लिए नीतियों की रचना करने के निम्नलिखित की तरह कुछ का इस्तेमाल किया है:नीतियों को लिखने के लिए boost :: mpl का उपयोग कैसे करें?

नीति वर्गों इस तरह दिखेगा:

struct Policy { 
    static void init(); 
    static void cleanup(); 
    //... 
}; 

template <class CarT, class CdrT> 
struct Cons { 
    static void init() { 
    CarT::init(); 
    CdrT::init(); 
    } 
    static void cleanup() { 
    CdrT::cleanup(); 
    CarT::cleanup(); 
    } 
    //... 
}; 

नीतियों रचना करने के लिए:

typedef Cons<Policy1, Cons<Policy2, Cons<Policy3, Policy4> > > MyPolicy; 

MyPolicy का उपयोग करें:

init_with<MyPolicy>(...); 
//... 
cleanup_with<MyPolicy>(...); 

जहां वे कॉल करेंगे:

MyPolicy::init_options(); // calls Policy1 to 4's init in order 

और

MyPolicy::cleanup(); // calls Policy1 to 4's cleanup in reverse order 

अनिवार्य रूप से, विपक्ष यहाँ एक प्रकार सूची निर्माण करती है। यह बहुत सीधे आगे है। हालांकि typedef विपक्ष लाइन थोड़ी बदसूरत है। यह नीति combiner कि यह कर सकते हैं के लिए आदर्श हो जाएगा:

typedef CombinePolicy<Policy1, Policy2, Policy3, Policy4> MyPolicy; 

जब से हम नीतियों की मनमानी संख्या हो सकती है, CombinePolicy C++ 0x, जो काटने में प्रयोगात्मक ही उपलब्ध है में variadic टेम्पलेट समर्थन की आवश्यकता होगी एज कंपाइलर्स। हालांकि, ऐसा लगता है कि बढ़ावा: एमपीएल लाइब्रेरी एक गुच्छा प्रीप्रोकैसिंग चाल का उपयोग कर समस्या के चारों ओर हल/काम किया। मुझे लगता है कि मैं की तरह कुछ इस्तेमाल कर सकते हैं:

typedef mpl::list<Policy, Policy2, Policy3, Policy4> Policies; 

और फिर कहता है:

init_with<Policies>(...); 

जो तब का प्रयोग करेंगे:

typedef iter_fold<Policies, begin<Policies>::type, 
        some_magic_lambda_expression>::type MyPolicy; 

जाहिर है, मैं एक छोटे से परेशानी पता लगाना है some_magic_lambda_expression यहां। मुझे यकीन है कि यहां एमपीएल विशेषज्ञों के लिए यह काफी मामूली है।

अग्रिम धन्यवाद।

उत्तर

1

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

आप एमपीएल के क्रम एल्गोरिदम की कोशिश कर सकते, की तरह:

for_each<Policies>(InitPolicy()); 

साथ

struct InitPolicy() { 
    template<class Policy> 
    void operator() (Policy& p) { p.init_options(); } 
}; 
+0

वहाँ में एक छोटे से बग है:

typedef fold<Policies, Null, Cons<_1, _2> >::type MyPolicy; 

आदेश में यह काम करने के लिए, मैं अशक्त प्रकार और विपक्ष के लिए एक विशेषज्ञता प्रदान करने की आवश्यकता आपका उदाहरण यह उदाहरण के लिए काम करने के लिए बना सकता है। मैं प्रत्येक विधि के लिए for_each का उपयोग कर सकते हैं। लेकिन मैं एक संयुक्त नीति को पसंद करता हूं जिसे चारों ओर पारित किया जा सकता है, यानी, मैं ऑर्डर को फॉरटाइम के बजाए रनटाइम के बजाए संकलित समय पर लागू करना पसंद करता हूं। – ididak

+0

जैसा कि मैंने इसे देखा है, आप संकलन समय पर केवल मेटाफंक्शन को कॉल कर सकते हैं, मुझे संकलन समय में init_options() या किसी अन्य सादे फ़ंक्शन को कॉल करने का कोई तरीका नहीं दिखता है। मैं समझ गया कि आप रनटाइम पर init_with को कॉल करके पॉलिसी सूची में सभी नीतियों को स्वचालित रूप से लागू करना चाहते हैं, जो कि_एच करता है। कृपया – tabdamage

+0

को स्पष्ट करें, लक्ष्य को मेरे मूल उदाहरण के रूप में लागू किए गए आदेश के साथ संकलित समय पर एक पॉलिसी क्लास लिखना है और वास्तव में विधियों को वास्तव में रनटाइम पर लागू किया जाता है जैसे MyCombinedPolicy :: init_options() आदि – ididak

1

मुझे लगता है कि आप की तरह कुछ के लिए देख रहे:

typedef 
    iter_fold< 
    Policies, 
    begin<Policies>::type, 
    Cons<_1,_2> 
    >::type 
    MyType; 

तुम भी हो सकता है कि inherit_linearly<> में देखना चाहें यदि आप कुछ प्रकार के सीआरटीपी को बुलाएंगे आधार के कार्यों को संकलित समय पर कड़ी मेहनत की गई।

+0

यह मेरा मूल अनुमान था, लेकिन मुझे नहीं लगता कि यह सही है (संकलन आदि नहीं होगा) हालांकि। इसके अलावा मुझे नहीं लगता कि legisl_linearly यहां मॉडल फिट बैठता है। मैं संरचना को तुच्छ और घोषणात्मक बनाना चाहता हूं। एक प्रकार अनुक्रम सबसे आसान होगा। – ididak

9

चूंकि किसी ने भी संतोषजनक रूप से प्रश्न का उत्तर नहीं दिया, इसलिए मैंने कभी भी :: एमपीएल स्रोत को बढ़ावा देने में बिताया। मैन, यह मैक्रोज़ की परतों और विशेषज्ञता वर्गों की सैकड़ों लाइनों के साथ सुंदर नहीं है।अब मेटा प्रोग्रामिंग को आसान बनाने और हमारे लिए पोर्टेबल बनाने के लिए बूस्ट लाइब्रेरी के लेखकों के लिए अब मुझे अधिक प्रशंसा है। उम्मीद है कि सी ++ 0 एक्स पुस्तकालय लेखकों के जीवन को भी आसान बना देगा।

वैसे भी, समाधान सरल और सुरुचिपूर्ण साबित होता है।

पहला iter_fold वह नहीं है जो मैं चाहता हूं, क्योंकि मैं यह समझ नहीं पाया कि एक इटरेटर को कैसे निर्दिष्ट किया जाए जिसे किसी नल प्रकार से संदर्भित किया जा सके। इसलिए मैं गुना के साथ आसपास fiddled और पाते हैं निम्नलिखित:

struct Null { }; 

template<class PolicyT> 
struct Cons<Null, PolicyT> { 
    static void init() { PolicyT::init(); } 
    static void cleanup() { PolicyT::cleanup(); } 
}; 
+0

सुरुचिपूर्ण, मैं सहमत हूं। अलेक्जेंड्रेस्कस टाइप_लिस्ट की तरह दिखता है। एक निश्चित स्तर पर, उपयोगकर्ताओं को चीजों को अदृश्य बनाने के लिए आवश्यक जादू काफी परेशान है ... – tabdamage

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

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