2013-01-03 25 views
10

कैसे मानक पुस्तकालय वास्तव में कार्यान्वित किया जाता है मैं दृश्य स्टूडियो में सभी कंटेनर निरीक्षण कर रहा हूँ .. यहाँ मैं कुछ उत्सुक संरचना के बारे में अधिक जानने की कोशिश कर:क्या करता है (टेम्पलेट) rebind <> करते हैं?

एक std::list<> के कुछ आधार वर्ग में निम्नलिखित typedef

पाया जाता है
typedef typename _Alloc::template rebind<_Ty>::other _Alty; 

जहां "_Alloc" आवंटक टेम्पलेट तर्क (और निहित प्रकार _Ty) से मेल खाता है। मुझे इस "कीवर्ड" की अच्छी व्याख्या खोजने में परेशानी है। अब तक का सबसे अच्छा संकेत है कि यह आवंटक इंटरफ़ेस का हिस्सा है। हालांकि cppreference भी इसे समझाने में बहुत अच्छा नहीं है।

यह template rebind<> क्या करता है? और उस स्थान पर क्यों जरूरी है?

+0

संबंधित, देखें [आवंटन :: हमारे पास टेम्पलेट टेम्पलेट पैरामीटर होने पर आवश्यक क्यों है?] (Http://stackoverflow.com/q/12362363) – jww

उत्तर

14

_Alloc टेम्पलेट किसी प्रकार की वस्तुओं को प्राप्त करने के लिए किया जाता है: प्रकार लेखन। कंटेनर में एक अलग प्रकार की वस्तुओं को आवंटित करने की आंतरिक आवश्यकता हो सकती है। उदाहरण के लिए, जब आपके पास std::list<T, A> है, तो आवंटक AT प्रकार की ऑब्जेक्ट आवंटित करने के लिए है, लेकिन std::list<T, A> को वास्तव में कुछ नोड प्रकार की ऑब्जेक्ट आवंटित करने की आवश्यकता है। नोड प्रकार _Ty पर कॉल करने के लिए, std::list<T, A> को _Ty ऑब्जेक्ट्स के लिए आवंटन प्राप्त करने की आवश्यकता है जो A द्वारा आवंटित आवंटन तंत्र का उपयोग कर रहा है।

typename _A::template rebind<_Ty>::other 

संबंधित प्रकार निर्दिष्ट करता है। अब, वहाँ इस घोषणा में कुछ वाक्यात्मक खीज कर रहे हैं: एक टेम्पलेट तर्क

  1. rebind के बाद से _A और _A के एक सदस्य टेम्पलेट है है, rebind एक आश्रित नाम हो जाता है। यह इंगित करने के लिए कि एक आश्रित नाम एक टेम्पलेट है, इसे template द्वारा पूर्ववर्ती करने की आवश्यकता है। template कीवर्ड के बिना < को ऑपरेटर से कम माना जाएगा।
  2. नाम other भी एक टेम्पलेट तर्क पर निर्भर करता है, यानी, यह भी एक आश्रित नाम है। यह इंगित करने के लिए कि एक आश्रित नाम एक प्रकार है, typename कीवर्ड की आवश्यकता है।
+0

प्रतीक्षा करें, लेकिन इसका मतलब यह होगा कि (जब सूची 'std है :: सूची '); ' रिबाइंड 'अनावश्यक हो जाता है? क्योंकि यह "टी" से "टी" प्रकार में परिवर्तित होगा? – paul23

+0

@ paul23: यदि '_Ty' टेम्पलेट तर्क के बजाय की तरह कुछ है' typedef _Node <_T> _Ty', सुनिश्चित करें कि संभाजक उचित प्रकार बनाता है बनाने के लिए उपयोगी हो सकता है। हालांकि मुझे पूरा यकीन है कि 'st' :: सूची में' ए' 'टी' ऑब्जेक्ट्स से निपटने में सक्षम होने की आवश्यकता है, एक अलग के आवंटन को पास किया जा सकता है। मुझे मानक आवश्यकताओं के बारे में निश्चित नहीं है। यह विभिन्न प्रकार के लिए आवंटकों का समर्थन करने के लिए एक विस्तार हो सकता है। –

+0

टी की सूची टी के सदस्य के रूप में टी युक्त आवंटित नोड्स। तो टी आवंटक सीधे इसके लिए बेकार है। इसके बजाय यह एक नया बनाता है। आपकी टिप्पणी मेरे लिए कोई मतलब नहीं है @ paul23 – Yakk

3

rebind एक प्रकार के लिए स्मृति आवंटित करने के लिए है जो कंटेनर के तत्व प्रकार से अलग है। this MSDN article से लें:

उदाहरण के लिए, एक का एक संभाजक वस्तु अल को देखते हुए, आप अभिव्यक्ति के साथ प्रकार _Other की एक वस्तु आवंटित कर सकते हैं:

A::rebind<Other>::other(al).allocate(1, (Other *)0)

या, आप के द्वारा अपने सूचक प्रकार नाम कर सकते हैं

A::rebind<Other>::other::pointer

0

जाँच कृपया इस http://www.cplusplus.com/reference/memory/allocator/

आप

rebind < देखेंगे ...> वास्तव में वर्ग संभाजक के एक सदस्य जो कार्यान्वयन के स्रोत कोड दिए बिना एसटीएल का हिस्सा है।

जैसा कि आप देखते हैं, < को पुनर्जीवित करें ...> एक टेम्पलेट भी है और यह आवंटित वर्ग को मेरे रिबिंड सदस्य में क्या है, यह जानने के लिए एक प्रकार के लायक है।

तो अपने कथन पर वापस: टाइपपीफ टाइपनाम _ अलाक :: टेम्पलेट रिबाइंड < _Ty> :: अन्य _Alty; अगर आप टेम्पलेट छोड़े गए: typedef typename _Alloc :: rebind < _Ty> :: अन्य _Alty; आप आसानी से समझ सकते हैं कि rebind _Alloc का सदस्य है, लेकिन संकलक समझ नहीं सकता है।

टेम्पलेट, टेम्पलेट rebind < _Ty> जा रहा है rebind की प्रकृति को देखते हुए की जरूरत है और पूरे नहीं दो भागों के रूप में व्यवहार किया जाता है। stdc के कोड में

0

उदाहरण ++:

/usr/include/4.8/ext/new_allocator.h

rebind संभाजक वर्ग के एक सदस्य के रूप में परिभाषित किया गया है संरचना; इस संरचना एक सदस्य अन्य है कि एक अलग तर्क प्रकार के लिए विशेष संभाजक का एक उदाहरण के रूप में परिभाषित किया गया है परिभाषित करता है

template<typename _Tp> 
    class new_allocator 
    { 
    public: 
     ... 
     template<typename _Tp1> 
     struct rebind 
     { typedef new_allocator<_Tp1> other; }; 

जब (अन्य सदस्य एक संभाजक वर्ग कि वस्तुओं की एक अलग प्रकार बनाता है सकते हैं परिभाषित करता है) यह प्रयोग किया जाता है:

typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type; 

संभाजक के प्रकार

typename _Alloc::template rebind<_Tp>::other 
के रूप में संदर्भित है जो तब एक ही बात के लिए कोई छोटा नाम के रूप में इस्तेमाल किया जा सकता -

अब typedef _Tp_alloc_type परिभाषित करने के लिए प्रयोग किया जाता है।

एक उदाहरण उपयोग std :: सूची जहां आंतरिक सूची नोड भी अपने संभाजक, जो तर्क संभाजक से नए सिरे से परिभाषित की जरूरत है।

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