2011-11-29 5 views
6

मैं पढ़ रहा हूँ:केवल गैर-निरंतर मानचित्र क्यों सहयोगी सरणी-जैसे प्रत्यक्ष तत्व पुनर्प्राप्ति प्रदान करते हैं?

मानक सी ++ लाइब्रेरी: एक ट्यूटोरियल और निकोलाई एम Jossuttis द्वारा संदर्भ

जब मैं में कुछ एसटीएल तंत्र का उपयोग करने के लिए जा रहा हूँ बुक मेरे लिए जाने के है किसी भी महत्वपूर्ण तरीके से। वैसे भी, मैं जल्दी से std :: नक्शे और संबंधित एल्गोरिदम पर अध्याय फिर से पढाना था और मैं एक वाक्य मैं के बारे में पहले नहीं सोचा था देखा:

गैर निरंतर नक्शे प्रत्यक्ष तत्व पहुँच के लिए एक सबस्क्रिप्ट ऑपरेटर प्रदान करते हैं। हालांकि, सबस्क्रिप्ट ऑपरेटर का सूचकांक तत्व की अभिन्न स्थिति नहीं है। ... आदि

एक सहयोगी सरणी में केवल गैर-निरंतर मानचित्रों का उपयोग क्यों किया जा सकता है? ऐसा लगता है कि इस मामले में केवल पढ़ने के लिए अर्थशास्त्र प्रदान करना काफी आसान होगा। मुझे लगता है कि अपवाद संभव होगा यदि आपने किसी कुंजी के साथ तत्व को पुनर्प्राप्त करने का प्रयास किया जो अस्तित्व में नहीं था (साइन इन करें यदि आप स्थिर होने पर मानचित्र पर कोई नई कुंजी/मान नहीं जोड़ सकते हैं)।

अगर कोई कुछ प्रकाश डाल सकता है तो मैं इसके पीछे तर्क समझना चाहता हूं :) धन्यवाद!

+0

यदि कोई मिलान तत्व नहीं है तो 'std :: map' के' const' instance 'उदाहरण पर काम करने के लिए आप' map ["foo"] 'की अपेक्षा कैसे करेंगे? यह इसे नहीं बना सकता क्योंकि 'नक्शा' का आधार है और एक निरीक्षण फेंकना गैर-कॉन्स व्यवहार से भिन्न होगा जो खतरनाक हो सकता है। – ereOn

उत्तर

11

क्यों केवल गैर-निरंतर नक्शे तरीके की तरह एक साहचर्य सरणी में इस्तेमाल किया जा सकता: दूसरी ओर, find() पुनरावर्तक जिसका constness नक्शा ही का है देता है?

क्योंकि वे ऑपरेटर किसी विशेष कुंजी से जुड़े ऑब्जेक्ट का संदर्भ वापस लौटते हैं। यदि कंटेनर में पहले से ही कोई ऑब्जेक्ट नहीं है, तो operator[] डिफ़ॉल्ट ऑब्जेक्ट को सम्मिलित करता है। अब, यदि कंटेनर स्थिर है, तो आप इसमें कोई ऑब्जेक्ट नहीं डाल सकते हैं, और आप गैर-मौजूदा ऑब्जेक्ट्स के संदर्भ को वापस नहीं कर सकते हैं, यही कारण है कि ये ऑपरेटर केवल गैर-स्थिर कंटेनरों के लिए उपलब्ध हैं।

उस मामले में अपवाद फेंकना संभव है, लेकिन एक सामान्य सामान्य मामलों तक पहुंचने का सबसे अच्छा तरीका नहीं है जब किसी दिए गए कुंजी के लिए ऑब्जेक्ट मौजूद नहीं है। असल में, अपवाद बेहद महंगा हैं और असाधारण स्थितियों के लिए हैं, और उपरोक्त एक नहीं है, इसलिए यह इसके लायक नहीं है।

बेहतर तरीका एक इटरेटर वापस करना होगा, लेकिन फिर उपयोगकर्ता को यह जांचना होगा कि यह "अंत" नहीं है, जो find() पर कॉल करने के समान उपयोग केस बना देगा, इसलिए बेकार। निरंतर-केवल कंटेनर के लिए इटरेटर्स या पॉइंटर्स लौटाना भी संभव है, लेकिन यह अर्थशास्त्र को थोड़ा सा तोड़ देता है और भ्रमित होता है।

1

[] -operator कंटेनर mutates: यदि कुंजी मौजूद नहीं है, यह बनाया जाएगा:

return m[1];  // **creates** m[1] if it doesn't exist 

return *m.find(1) // UB if m[1] doesn't exist (dereferencing m.end()) 

इसके अलावा, [] हमेशा एक गैर निरंतर संदर्भ देता है, ताकि आप m[1] = 2; कह सकते हैं।

map_t m; 
*m.find(1) = 2; // Only OK if m[1] exists 
// *const_cast<map_t const &>(m).find(1) = 2; // error 
1

[] ऑपरेटर मानचित्र को संशोधित करता है, यदि कुंजी मौजूद नहीं है।

यदि कुंजी मौजूद नहीं है, तो नक्शा कुंजी के साथ एक नई प्रविष्टि बनाता है, और संबंधित मान के लिए एक डिफ़ॉल्ट मान बनाता है, और इसके संदर्भ को वापस कर देता है।ऐसा होने के लिए, operator[] को गैर-कॉन्स्ट फ़ंक्शन होना चाहिए, जिसका अर्थ है कि यह std::map के उदाहरण पर संचालित नहीं हो सकता है।

8

सी ++ में आप at() का उपयोग कर सकते हैं ताकि "मैप किए गए मान प्राप्त करें, अन्यथा अपवाद फेंक दें" व्यवहार प्राप्त करें। operator[] ओवरलोडिंग दो अलग-अलग चीजें करने के लिए (यानी या तो नई जोड़ी या फेंक डालें) इस पर निर्भर करता है कि नक्शा स्थिर है या नहीं, यह बहुत भ्रमित और त्रुटि-प्रवण होगा।

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