2010-06-08 15 views
6

निम्नलिखित न्यूनतम उदाहरण:unordered_map में बिडरेक्शनल इटरेटर्स?

#include <iostream> 

#include <boost/unordered_map.hpp> 

int main() 
{ 
     boost::unordered_map<int, int> m; 
     boost::unordered_map<int, int>::const_iterator i; 

     m.insert(std::make_pair(1, 2)); 

     i = m.end(); 
     --i; 

     std::cout << i->first << " -> " << i->second << std::endl; 

     return 0; 
} 

... संकलित करने के लिए विफल रहता है।

bidi.cxx: In function ‘int main()’: 
bidi.cxx:13: error: no match for ‘operator--’ in ‘--i’ 

Boost's own documentation के अनुसार:

iterator, const_iterator कम से कम आगे श्रेणी के हैं।

ऐसा लगता है कि वे सब कुछ हैं। क्यूं कर? हैश-मैप किस तकनीकी प्रतिबंध को लगाता है जो इटरेटर को द्विपक्षीय होने से रोकता है?

(जीसीसी संस्करण 4.1.2, संस्करणों 1.40.0 और 1.43.0 बढ़ावा।)

+0

यह शुद्ध अटकलें आपको दिमाग में रखती है, लेकिन ध्यान रखें कि आपके पीछे कुछ पीछे और आगे की ओर जाने में सक्षम होने के बाद प्रत्येक नोड को अगले आइटम और पिछली वस्तु में पॉइंटर होना होगा। यदि यह नक्शा केवल अगली वस्तुओं पर केवल पॉइंटर्स के साथ लागू किया गया था, तो आपके इटरेटर को यह पता लगाने का कोई तरीका नहीं होगा कि वर्तमान नोड से पहले क्या हुआ था, और इस प्रकार पीछे जाने का कोई तरीका नहीं था। –

+0

ईमानदारी से मुझे यह अजीब लगता है (हालांकि कभी-कभी उपयोगी) कि unordered_maps भी iterators है। –

+0

@Niki योशीचुची: मैंने पर्ल में इसी अवधारणा का उपयोग किया है। आम तौर पर, मैं चाहता हूं कि पर्ल को सहयोगी सरणी के रूप में कार्य करना पड़े, लेकिन कभी-कभी मैं पूरे हैश में कुछ करना चाहता हूं। पर्ल में, मैं चाबियों की सूची प्राप्त करने के लिए 'कुंजी' फ़ंक्शन का उपयोग करता हूं, और इसके माध्यम से पुनरावृत्ति करता हूं, जबकि सी ++ में स्पष्ट समतुल्य एक आगे इटरेटर होता है। मैं वास्तव में किसी भी डेटा संग्रह पर 'foreach' के बराबर करने की क्षमता को याद करता हूं। –

उत्तर

10

कोई तकनीकी कारण है कि एक unordered_map द्विदिश iterators नहीं हो सकता है। मुख्य कारण यह है कि यह कार्यान्वयन के लिए अतिरिक्त लागत जोड़ देगा, और डिजाइनरों ने सोचा था कि किसी को भी हैश मैप में बिडरेक्शनल इटरेटर्स की आवश्यकता नहीं होगी। आखिरकार, हैश में कोई ऑर्डर नहीं है, और इसलिए इटरेटर आपको ऑर्डर देता है जो आपको पूरी तरह से मनमाना देता है। पीछे की ओर एक निश्चित लेकिन मनमाने ढंग से आदेश देने के लिए आपको क्या देना होगा?

आम तौर पर, एक तत्व-दर-तत्व आधार पर unordered_map तक पहुंच जाएगा, या पूरे मानचित्र को पार करेगा। मैंने कभी भी पर्ल में खुद को नहीं किया है। ऐसा करने के लिए, एक आगे इटेटरेटर आवश्यक है, और इसलिए वहां एक है, और बूस्ट इसकी गारंटी देता है। बिडरेक्शनल इटरेटर्स होने के लिए, प्रत्येक प्रविष्टि में एक अतिरिक्त सूचक शामिल करना आवश्यक होगा, जो स्मृति उपयोग और प्रसंस्करण समय को बढ़ाता है।

मैं यहां एक अच्छा, व्यावहारिक, उपयोग करने वाले मामले के साथ बिडरेक्शनल इटरेटर्स के लिए उपयोग नहीं कर रहा हूं। यदि आप कर सकते हैं, तो आप बूस्ट रखरखावकर्ताओं को इस पर विचार करने के लिए कह सकते हैं, हालांकि आप लगभग निश्चित रूप से सी ++ 0x के लिए बहुत देर हो चुकी हैं।

+0

दरअसल, मैंने सोचा था कि हैश-मैप्स के बारे में थोड़ा मनमाना क्रम में परिणाम लौटने के बारे में काफी विश्वास था। सामान्य उपयोग-मामले या तो एक लुकअप हैं, या पूर्ण पुनरावृत्ति हैं। मेरे सिर में, उन्हें हमेशा बाल्टी के वेक्टर के साथ लागू किया गया था, और एक बाल्टी एक std :: सूची है। कभी-कभी एकल-लिंक्ड-सूची का उपयोग करने की बचत को कभी नहीं माना जाता है। – Thanatos

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