2009-10-12 6 views
5

मैं अभी एसटीएल स्रोत कोड पढ़ रहा हूं। हालांकि मैं stl_list.h में जो पढ़ रहा हूं उसमें मांस को समझता हूं, मैं निम्नलिखित स्निपेट को पूरी तरह से समझना चाहता हूं (मुख्य रूप से टेम्पलेट सिंटैक्स से संबंधित, मुझे लगता है)।सी ++ टेम्पलेट सिंटैक्स (एसटीएल लाइब्रेरी स्रोत कोड) के बारे में एक प्रश्न

टेम्पलेट

class _List_base { 
    ... 
    typedef typename _Alloc::template rebind<_List_node<_Tp> >::other _Node_Alloc_type; //(1). 

    ... 
    typedef _Alloc allocator_type; 
    get_allocator() const 
    { return allocator_type(*static_cast< 
          const _Node_Alloc_type*>(&this->_M_impl)); } // (2) 
    ... 
}; 

कोई व्याख्या कर सकते हैं कि हम एक "टेम्पलेट" रेखा (1) में _Alloc निम्नलिखित की ज़रूरत है? (और इस लाइन का पूर्ण स्पष्टीकरण दे रहे हैं?)

क्या कोई यह समझा सकता है कि हम _Node_Alloc_type को _Alloc लाइन (2) में क्यों डाल सकते हैं?

+3

आपको यह स्पष्ट करना चाहिए कि आप जिस एसटीएल को देख रहे हैं उसका विशेष कार्यान्वयन क्या है। जबकि एसटीएल इंटरफेस स्टैंडराइज किया गया है, कार्यान्वयन एक विक्रेता से दूसरे में भिन्न होता है। –

उत्तर

12

template कीवर्ड को क्लास टेम्पलेट के रूप में rebind नाम की पहचान करने के लिए आवश्यक है। इसके बिना, rebind को एक चर या स्थिर माना जा सकता है (इस मामले में typename कीवर्ड के कारण एक प्रकार) और निम्नलिखित < को ऑपरेटर से कम के रूप में व्याख्या किया जा सकता है।

यह कुछ हद तक typename कीवर्ड (जो कि other को एक प्रकार के रूप में पहचानने के लिए आवश्यक है) के समान है।

प्रत्येक आवंटक को मेटा-फ़ंक्शन (यानी एक वर्ग टेम्पलेट) प्रदान करने की आवश्यकता होती है जिसे rebind कहा जाता है जो एक ही आवंटक को लौटाता है लेकिन एक अलग प्रकार के लिए। दूसरे शब्दों में,

Alloc<T>::rebind<U>::other 

नामों के रूप में

Alloc<U> 

एक ही प्रकार अपने प्रश्न के दूसरे भाग में अधिक संदर्भ के बिना जवाब देना मुश्किल है। _M_impl का प्रकार क्या है? उस प्रकार को कैसे परिभाषित किया जाता है?

2

यह std :: सूची के जीसीसी कार्यान्वयन की तरह दिखता है। उस मामले में, संदर्भ है:

struct _List_impl : public _Node_Alloc_type { ... }; 
_List_impl _M_impl; 

और तुम सदस्य समारोह की वापसी प्रकार लिखना भूल:

typedef _Alloc allocator_type; 
allocator_type 
get_allocator() const 
{ return allocator_type(*static_cast<const _Node_Alloc_type*>(&this->_M_impl)); } 

के लिए (1)

उत्तर जब एक जोड़ने _Tp प्रकार की सूची में नोड, वास्तव में आवंटित करने की आवश्यकता है, कोई ऑब्जेक्ट _Tp नहीं है, लेकिन एक सूची नोड _Tp (_List_node<_Tp>) है।

तो std :: सूची को _List_node<_Tp> आवंटित करने में सक्षम होना आवश्यक है, लेकिन इसे _Tp के लिए आवंटन प्रदान किया गया है। यह जहां टेम्पलेट typedef rebind काम में आता है: यह यह संभव इस rebind का उपयोग प्रकार टी

के लिए एक संभाजक से के लिए प्रकार यू एक संभाजक प्राप्त करने के लिए बनाता है, हम प्रकार _Alloc<_Tp> से एक _Alloc<_List_node<_Tp> > मिलता है।


के लिए (2) टिप्पणी के रूप में स्रोत फ़ाइल में उत्तर:

// NOTA BENE 
// The stored instance is not actually of "allocator_type"'s 
// type. Instead we rebind the type to 
// Allocator<List_node<Tp>>, which according to [20.1.5]/4 
// should probably be the same. List_node<Tp> is not the same 
// size as Tp (it's two pointers larger), and specializations on 
// Tp may go unused because List_node<Tp> is being bound 
// instead. 
// 
// We put this to the test in the constructors and in 
// get_allocator, where we use conversions between 
// allocator_type and _Node_Alloc_type. The conversion is 
// required by table 32 in [20.1.5]. 

यह माना जाता है कि _Alloc के प्रकार _Node_Alloc_type सी ++ मानक के अनुसार के रूप में ही है, इसलिए static_cast दावा करता है कि रूपांतरण कानूनी है।

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