2009-05-23 13 views
10

मैंने 'आधुनिक सी ++ डिज़ाइन' में टाइपलिस्ट के बारे में पढ़ा है और मैं इसे प्रकार के लिए किसी प्रकार के संघ के रूप में समझता हूं। एक टाइपलिस्ट में भिन्न, गैर-संबंधित प्रकार डालने से, कोई भी विरासत के बिना, एक से अधिक प्रकार का प्रतिनिधित्व करने के लिए इसका उपयोग कर सकता है। मैंने आदिम प्रकारों के साथ कुछ सरल कार्यों में टाइपलिस्टिस्ट का परीक्षण किया, लेकिन मैं उनमें से कोई भी काम करने के लिए नहीं मिला।टाइपलिस्टिस्ट का उपयोग कैसे करें

कोई मुझे बता सकते हैं अगर typelists की मेरी unterstanding सही है और एक सरल असली दुनिया उदाहरण कैसे हर दिन औसत कोड में typelists उपयोग करने के लिए दे सकता है? अग्रिम में धन्यवाद।

बीटीडब्ल्यू, मैं विंडोज और विजुअल स्टूडियो 2005 और इसके कंपाइलर का उपयोग कर रहा हूं।

संपादित करें: मेरे उदाहरण चले गए हैं, मैं बनाम उन चीजों का परीक्षण करने में एकसैंडबॉक्स परियोजना का उपयोग करें। लेकिन यह शांत डोब्स ट्यूटोरियल में कोड करने के लिए समान था:

void SomeOperation(DocumentItem* p) 
{ 
    if (TextArea* pTextArea = dynamic_cast<TextArea*>(p)) 
    { 
     ... operate on a TextArea object ... 
    } 
    else if (VectorGraphics* pVectorGraphics = 
     dynamic_cast<VectorGraphics*>(p)) 
    { 
     ... operate on a VectorGraphics object ... 
    } 
    else if (Bitmap* pBitmap = dynamic_cast<Bitmap*>(p)) 
    { 
     ... operate on a Bitmap object ... 
    } 
    else 
    { 
     throw "Unknown type passed"; 
    } 
} 

यह काम करता है, लेकिन मैं विरासत जो भी ऐसा ही करने में सक्षम है पर लाभ नहीं दिख रहा। और गतिशील कास्ट आदिम प्रकार पर काम नहीं करते हैं। यह संभव एक वापसी मान के रूप में उपयोग करने के लिए की तरह है:

typedef Typelist<int, string> mylist 
mylist myfunction() { 
    if(foo == bar) 
     return 5; 

    return "five"; 
} 
+0

कोड का एक उदाहरण जोड़ें जो आपके प्रश्न पर काम नहीं करता है। –

उत्तर

18

typelists प्रकार के सामान्य संकलन समय संग्रह हैं। आप dynamic_cast का उपयोग करते हैं, तो आप, बात को अनदेखा कर रहे हैं, क्योंकि यह आवश्यक नहीं किया जाना चाहिए, क्योंकि यह एक स्थिर है, संकलन समय अवधारणा।

यह काम करता है लेकिन मुझे विरासत पर लाभ दिखाई नहीं देता है जो ऐसा करने में सक्षम है।

आप जो कुछ भी चाहते हैं उससे कोई मौजूदा प्रकार का उत्तराधिकारी नहीं बना सकते हैं। क्योंकि इस मौजूदा प्रकार एक प्रकार या एक पुस्तकालय से एक प्रकार में बनाया जा सकता है यह केवल संभव नहीं है। प्रकार के किसी भी उचित संख्या (बजाय सिर्फ 2 की) के लिए (std :: जोड़ी में उदा) प्रकार की सूचियों के विस्तार के रूप में typelists के बारे में सोचो ।

typelists एक समारोह के तर्क का एक सेट के आसपास पारित करने के लिए एक सुविधा बनाने के लिए इस्तेमाल किया जा सकता है।यह कोड का एक टुकड़ा है जो 5 पैरामीटर (आधुनिक सी ++ डिज़ाइन से एक और अवधारणा) को टाइप करने वाले तर्कों के साथ एक ट्यूपे (अभी तक एक और) में दिए गए तर्कों के साथ सामान्यीकृत फ़ैक्टर को कॉल करता है जो टुपल में रखी गई वस्तुओं के प्रकार को परिभाषित करता है:

//functor is just a holder of a pointer to method and a pointer to object to call this 
//method on; (in case you are unfamiliar with a concept) 
template<class R, class t0, class t1, class t2, class t3, class t4> 
R call(Loki::Functor<R,LOKI_TYPELIST_5(t0, t1, t2, t3, t4 
    )> func, 
    Loki::Tuple<LOKI_TYPELIST_5(t0, t1, t2, t3, t4)> tuple) 
{ 
    ///note how you access fields 
    return func(Loki::Field<0>(tuple), Loki::Field<1>(tuple), 
     Loki::Field<2>(tuple), Loki::Field<3>(tuple), 
     Loki::Field<4>(tuple)); 
} 

//this uses the example code 
#include<iostream> 
using namespace std; 

int foo(ostream* c,int h,float z, string s,int g) 
{ 
    (*c)<<h<<z<<s<<g<<endl; 
    return h+1 
} 

int main(int argc,char**argv) 
{ 
    Loki::Functor<int,LOKI_TYPELIST_5(ostream*, int, float, string, int)> f=foo; 
    //(...) 
    //pass functor f around 
    //(...) 
    //create a set of arguments 
    Loki::Tuple<LOKI_TYPELIST_5(ostream*, int, float, string, int)> tu; 
    Field<0>(tu)=&cout; 
    Field<1>(tu)=5; 
    Field<2>(tu)=0.9; 
    Field<3>(tu)=string("blahblah"); 
    Field<4>(tu)=77; 
    //(...) 
    //pass tuple tu around, possibly save it in a data structure or make many 
    //specialized copies of it, or just create a memento of a call, such that 
    //you can make "undo" in your application; note that without the typelist 
    //you would need to create a struct type to store any set of arguments; 
    //(...) 
    //call functor f with the tuple tu 
    call(f,tu); 
} 

ध्यान दें कि केवल अन्य अवधारणाओं जैसे टुपल्स या मज़दूरों के साथ टाइपलिस्टिस्ट उपयोगी होने लगते हैं। इसके अलावा, मैं एक परियोजना में लगभग 2 वर्षों के लिए लोकी का अनुभव कर रहा हूं और टेम्पलेट कोड (इसमें से बहुत) के कारण DEBUG संस्करणों में एक्जिक्यूटिव के आकार बड़े होते हैं (मेरा रिकॉर्ड 35 एमबी या उससे भी अधिक था)। संकलन की गति पर भी थोड़ा सा हिट था। यह भी याद रखें कि सी ++ 0x शायद कुछ समकक्ष तंत्र को शामिल करने जा रहा है। निष्कर्ष: यदि आपको ऐसा करने की ज़रूरत नहीं है तो टाइपलिस्ट का उपयोग न करें।

+0

बहुत बहुत धन्यवाद, आपने मेरे लिए कुछ चीजों को मंजूरी दे दी है। मुझे लगता है कि मुझे फिर से अध्याय पढ़ना चाहिए। – DaClown

5

करता डा डॉब के जर्नल मदद से किसी से this लेख?

4

Typelists "पैरामीटर की सूची" गुजर मेटा प्रोग्राम हैं जो संकलन की प्रक्रिया के हिस्से के रूप में "अमल" टेम्पलेट का एक तरीका है।

इस प्रकार, वे "यूनियन" प्रकार के कुछ प्रकार उत्पन्न करने के लिए इस्तेमाल किया जा सकता है, लेकिन यह केवल एक संभव इस्तेमाल होता है।

"असली दुनिया" उदाहरण के लिए: हमने Comet लाइब्रेरी में COM ऑब्जेक्ट्स को लागू करते समय टाइपरिस्ट को स्वचालित रूप से "क्वेरी इंटरफेस" विधि उत्पन्न करने के तरीके के रूप में उपयोग किया।

यह आप इस तरह कोड लिखने की अनुमति दी:

class Dog : public implement_qi<make_list<IAnimal, INoisy, IPersistStream> > 
{ 
    // The implement_qi template has provided 
    // an implementation of COM's QueryInterface method for us without 
    // having to write an ugly ATL "message map" or use any Macros. 
    ... 
} 

इस उदाहरण में, "make_list" एक "प्रकार सूची" है, जो implement_qi टेम्पलेट फिर "से अधिक की गणना" कर सकता है उत्पन्न करने के लिए प्रयोग किया जाता है एक टेम्पलेट था generate the appropriate QueryInterface code

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