2010-10-21 10 views
9

मैं बस में स्थिरांक bools का उपयोग कर के खिलाफलाभ :: एमपीएल :: एक स्थिरांक bool

bool_<true> 

और

bool_<false> 

प्रकार का उपयोग कर के लाभों के बारे उलझन में हूँ के बजाय bool_ टेम्पलेट मेटाप्रोग्रामिंग का संदर्भ।

बूस्ट :: एमपीएल लाइब्रेरी स्पष्ट रूप से पहले दृष्टिकोण को पसंद करती है, और ऐसे bool_ को प्रबंधित करने में सहायता के लिए और_, या_ जैसे सहायक कार्यों को परिभाषित करती है। सशर्त मेटाफंक्शन जैसे if_ "पहले" (टेम्पलेट) तर्क के रूप में bool_ लेते हैं, लेकिन दृश्यों के पीछे "if" एक if_c metafunction है जिसे पहले (टेम्पलेट) तर्क के रूप में एक (कॉन्स) बूल की अपेक्षा करता है।

इस निर्णय के पीछे तर्क क्या हैं?

आपकी मदद के लिए अग्रिम धन्यवाद!

उत्तर

11

यहां एक छोटा सा उदाहरण है, मैं अब इन प्रकारों का उपयोग कैसे करता हूं। इस उदाहरण संभव नहीं होगा, स्थिरांक bool का उपयोग कर:

void do_something(boost::mpl::bool_<true>) 
{ 
    ... 
} 

void do_something(boost::mpl::bool_<false>) 
{ 
    ... 
} 

कॉल तर्क के प्रकार पर निर्भर इन दोनों कार्यों में से एक:

template<class T> 
void doIt(void) 
{ 
    do_something(boost::mpl::bool_<boost::is_pointer<T>::val>()) 
} 

इस मामले में या तो पहली या दूसरी समारोह होगा अगर टी टी सूचक है या नहीं तो इस तथ्य के आधार पर कहा जाता है। ये प्रकार आपको फ़ंक्शन ओवरलोडिंग का उपयोग करने की अनुमति देते हैं, जहां एक कॉन्स बूल का उपयोग करना संभव नहीं होगा। एक कॉन्स बूल के साथ आपको रनटाइम पर फैसला करना होगा, जो शाखा लेना है। यह विशेष रूप से महत्वपूर्ण है अगर फ़ंक्शन स्वयं टेम्पलेट्स होते हैं, जो सही ढंग से संकलित नहीं होते हैं, अगर वे उम्मीद के अलावा अन्य प्रकारों के लिए तत्काल थे, उदा। ऊपर की पहली फ़ंक्शन परिभाषा में कोड हो सकता है, जो केवल पॉइंटर्स के लिए संकलित करता है।

+0

धन्यवाद कि यह एक अच्छा उदाहरण है! – stepelu

+0

ओह हाँ, मैं अधिभार के बारे में भूल गया! – sbi

+2

यह एक अच्छा जवाब है, लेकिन यह आवश्यक से अधिक verbose है। आप 'do_something (boost :: is_pointer ()) लिख सकते हैं,' जो वही काम वही तरीके से करेगा। –

2

मुझे लगता है एक कारण यह है कि bool_<...> प्रकार के होते हैं, और जब उन्हें एक मेटा कार्यों के परिणाम के रूप में उपयोग कर, आप बंद करो और लगता है कि क्या आपके परिणाम एक प्रकार है करने की आवश्यकता नहीं होगी और आप

typedef some_type result; 
क्या करना है

या एक मूल्य, जो

const static ??? result = some_value; 

के रूप में लौटा दी है, जहां आप भी प्रकार का ट्रैक रखने के लिए है।

इसके अलावा, मुझे लगता है (मैं अभी तक Boost.MPL साथ काम नहीं किया) वे दोनों एक result प्रकार खुद को की चर्चा करते हुए नेस्ट है, ताकि आप सिर्फ उन्हें से पाने से मेटा कार्यों लिख सकते हैं:

template< bool b > 
struct my_meta_func : bool_<b> {}; 

और my_meta_func::result का आह्वान कर सकते हैं।

+0

आप दाईं ओर, केवल परिणाम हमेशा कहा जाता है कर रहे हैं ':: एमपीएल में type'। –

8

यह पर्याप्त समानता बनाने के बारे में है कि पुस्तकालय उपयोगी कार्यक्षमता प्रदान कर सकता है। एमपीएल प्रोटोकॉल है: "सभी मेटाफंक्शन तर्क (और रिटर्न) प्रकार हैं।" यह हमें एक टेम्पलेट लिखने की अनुमति देता है जो सामान्य रूप से मेटाफंक्शन पर काम कर सकता है।

template <template <class...> class some_metafunction> 
struct wrapper; 

एक बार जब आप टेम्पलेट तर्कों के कुछ गैर-प्रकार, लेखन इस तरह के एक आवरण बन जाता है होना करने के लिए अनुमति देते हैं: उदाहरण के लिए, इस टेम्पलेट किसी भी metafunction (या सी ++ 03 में एन के तर्क के साथ किसी भी metafunction) स्वीकार करता है असंभव।हम क्यों देखभाल करते हैं इसके एक व्यावहारिक उदाहरण के लिए, यह एकरूपता पुस्तकालय को अलग-अलग चुनने और एमपीएल लैम्ब्डा अभिव्यक्तियों का मूल्यांकन करने की अनुमति देती है। अगर मेटाफंक्शन तर्कों को गैर-प्रकार के होने की अनुमति दी गई थी, तो यह सुविधा लागू नहीं होगी, क्योंकि अपने तर्क xxx<a1,a2,a3,...> में बाहरी टेम्पलेट xxx को अलग करने के लिए आवश्यक सभी आंशिक विशेषज्ञता लिखने का कोई तरीका नहीं होगा।

कम दिलचस्प, यदि कम मान्य नहीं है, तो इसका कारण यह है कि एमपीएल में हमने जिस तरह से किया है, उतनी ही कम चीजें कम हो जाती हैं। तुलना:

and_<mf0<x,y>, mf1<z>, mf2<x,z> >::value 

बनाम

mf0<x,y>::value && mf1<z>::value && mf2<x,z>::value 
संबंधित मुद्दे