2011-12-19 16 views
7

मान लीजिए कि मैं एसटीएल में एक लिंक्ड सूची बनाएँ:एसटीएल में कस्टम आवंटकों को केवल वास्तविक डेटा आवंटित करें?

list<int, my_allocator<int> > data; 

तो मैं एक अधिक कुशल संभाजक उपयोग कर सकते हैं, के एक स्मृति पूल मान लीजिए। लेकिन क्या सूची को सूची में जाने के लिए आगे और पिछड़े पॉइंटर्स जैसी आंतरिक मेमोरी आवंटित करने की आवश्यकता नहीं है? इन्हें कैसे आवंटित किया जाएगा? सामान्य new या किसी भी तरह my_allocator का उपयोग कर?

+0

क्या आपका मतलब एसटीएल या सी ++ मानक लाइब्रेरी कार्यान्वयन है जो आपके चुने हुए टूलचेन के साथ जहाजों? और वह कौन सा है? –

+0

@ टॉमलाक गेट्टल, क्या? (प्रश्न के लिए +1) – avakar

+0

@avakar एसटीएल मूल रूप से एक एसजीआई परियोजना थी। तब से एसटीएल (जैसे एसटीएलपोर्ट) के कई कार्यान्वयन हुए हैं और इसमें से कुछ को कुछ बदलावों के बावजूद समिति द्वारा परिभाषित मानक पुस्तकालय में जोड़ा गया है। जिनमें से सभी * "एसटीएल" * छोड़ते हैं जो इस सवाल को प्रभावित कर सकते हैं। – dmckee

उत्तर

10

कंटेनर वास्तव में आपके स्वयं के बुक-रखरखाव सामग्री को आवंटित करने के लिए आपके आवंटक का पुनरुत्थान करता है। (ऐसा नहीं है कि यह एक std::list के लिए कोई फर्क होगा, लेकिन यह सामान्य रूप में सच है। *) यही कारण है कि मानक संभाजक आवश्यकताओं rebind टेम्पलेट के अस्तित्व जनादेश:

typedef typename Alloc::template rebind<MyInternalStuff>::other internal_allocator; 

यदि आपका संभाजक Alloc = my_allocator<T> है, तो internal_allocatormy_allocator<MyInternalStuff> हो जाता है ।

मेरा मानना ​​है कि यह उन कलाओं में से एक था जो इलेक्ट्रॉनिक कला सी ++ मानक पुस्तकालय के साथ थीं, यही कारण है कि उनकी EASTL लाइब्रेरी उन सभी आवंटकों के लिए एक अलग सम्मेलन का उपयोग करती है जो कड़े नियंत्रण प्रदान करती हैं।

*) आमतौर पर, प्रत्येक नोड कुछ प्रकार Node<T> में से एक अखंड वस्तु हो जाएगा, तो मैं std::list<T, Alloc>केवल कभी एक संभाजक के रूप में Alloc::rebind<Node<T>>::other का उपयोग करता है लगता है।

[एकाधिक संपादन के लिए खेद है; मैंने आउटपुट को उलझाया और इसे सही तरीके से समझ नहीं लिया; अब मैं अलग-अलग प्रत्येक कंटेनर को मुद्रित करता हूं और आउटपुट को तदनुसार तय करता हूं। std::list वास्तव में केवल एक संभाजक की आवश्यकता होती है]


अद्यतन:। बस गिगल्स के लिए, मैं एक छोटे से demangling-संभाजक जो निर्माण पर अपनी ही typename प्रिंट लिखा था।

#include <unordered_map> 
#include <set> 
#include <deque> 
#include <list> 
#include <vector> 
#include <map> 

#include <iostream> 

int main() 
{ 
    std::cout << "----- unordered_map<int, double> -----------" << std::endl; 
    std::unordered_map<int, double, std::hash<int>, std::equal_to<int>, funky_allocator<std::pair<const int, double>>> m { {1, 1.2} }; 
    std::cout << "----- set<int> -----------------------------" << std::endl; 
    std::set<int, std::less<int>, funky_allocator<int>> s; 
    std::cout << "----- deque<int> ---------------------------" << std::endl; 
    std::deque<int, funky_allocator<int>> d; 
    std::cout << "----- list<int> ----------------------------" << std::endl; 
    std::list<int, funky_allocator<int>> l; 
    std::cout << "----- vector<int> --------------------------" << std::endl; 
    std::vector<int, funky_allocator<int>> c; 
    std::cout << "----- map<int, bool> -----------------------" << std::endl; 
    std::map<int, bool, std::less<int>, funky_allocator<std::pair<const int, bool>>> n { { 1, true } }; 
} 

और यहाँ उत्पादन:

----- unordered_map<int, double> ----------- 
Default-construct: funky_allocator<std::pair<int const, double> > 
Copy-construct: funky_allocator<std::__detail::_Hash_node<std::pair<int const, double>, false> > 
Copy-construct: funky_allocator<std::__detail::_Hash_node<std::pair<int const, double>, false>*> 

----- set<int> ----------------------------- 
Default-construct: funky_allocator<std::_Rb_tree_node<int> > 

----- deque<int> --------------------------- 
Default-construct: funky_allocator<int> 
Copy-construct: funky_allocator<int*> 

----- list<int> ---------------------------- 
Default-construct: funky_allocator<std::_List_node<int> > 

----- vector<int> -------------------------- 
Default-construct: funky_allocator<int> 

----- map<int, bool> ----------------------- 
Default-construct: funky_allocator<std::_Rb_tree_node<std::pair<int const, bool> > > 

विवरण आधार पर बदलती हैं, जिस पर निर्माता प्रयोग किया जाता है: यहाँ इनपुट है कंटेनरों set और map की तरह केवल कुछ मंगलाचरण में "सही" संभाजक का निर्माण हो सकता है, जबकि दूसरे में वे पहले निर्दिष्ट आवंटक का ऑब्जेक्ट बना सकते हैं। किसी भी तरह से, निर्दिष्ट आवंटक को कुछ कंटेनर के लिए कभी भी उपयोग नहीं किया जाता है, और केवल रिबाउंड संस्करण का उपयोग किया जाता है।

+0

आपके लिए धन्यवाद-पता-क्या;) –

+0

+1, हालांकि आप 'rebind' से पहले 'टेम्पलेट' खो रहे हैं :) – avakar

+0

@avakar: आप सही हैं, मैंने अभी देखा है! असल में, मैंने अभी अपना खुद का अपमानजनक आवंटक लिखा है जो तत्कालता पर अपने स्वयं के वर्ग का नाम प्रिंट करता है ताकि यह जांच सके कि कितने अलग-अलग मिश्रक कुछ लोकप्रिय कंटेनर की आवश्यकता है। –

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