2011-02-06 7 views
7

this other question asking about how comparing pointers is supposed to be interpreted सी ++ स्टडी wrt है।क्या ऑर्डर करने वाले एसटीएल कंटेनर में कुंजी के रूप में पॉइंटर्स की अनुमति है?

तो मैं सोच रहा था क्या सी ++ कक्षा आदेश दिया मानक पुस्तकालय (एसटीएल) कंटेनरों में कुंजी के रूप में संकेत का उपयोग कर के बारे में क्या कहना है - यानी एक

std::map<T1*, T2>

करने की अनुमति दी है और इस वजह से है std::less या builtin operator < का विनिर्देशन?

+0

बीटीडब्ल्यू, क्या आप पते को कुंजी के रूप में उपयोग करने के लिए कुंजी या मूल्य के रूप में उपयोग करना चाहते हैं? बाद के मामले में आपको एक कस्टम तुलनित्र – sellibitze

+0

संबंधित प्रदान करना होगा: [यदि किसी सरणी के भीतर पॉइंटर पॉइंट की जांच हो रही है] (http://stackoverflow.com/questions/4657976/) – fredoverflow

उत्तर

11

हाँ, क्योंकि यह std::less है, जो एक कुल आदेश भले ही < नहीं है में परिणाम के लिए आवश्यक है उपयोग करता है। (< को अलग-अलग पॉइंटर्स को समान अनुक्रमों के बराबर बराबर करने की अनुमति दी जाएगी, जिसके परिणामस्वरूप map आदि का अजीब व्यवहार होगा यदि आप विभिन्न अनुक्रमों से पॉइंटर्स डालें)।

+1

इस वाक्यांश को थोड़ा अलग करने के लिए: नीचे दिए गए उत्तर में टिप्पणी से विक्रेता को उद्धृत करने के लिए: "... पॉइंटर्स को सहयोगी कंटेनर में चाबियों के रूप में उपयोग करना सुरक्षित है। लेकिन इसका ऑपरेटर कम से कम ऑपरेटर के साथ कुछ लेना देना नहीं है क्योंकि std :: less इन कंटेनर के लिए डिफ़ॉल्ट तुलनित्र है और सी ++ टीडी सूचक प्रकार के मामले में std :: कम के लिए विशेष गारंटी देता है। ... " –

-3

हां। पॉइंटर्स ऑपरेटर <() के माध्यम से तुलनीय हैं।

संकेत दिए गए एक ही वस्तु के भीतर एक ही सरणी के तत्वों या तत्वों को इंगित नहीं है, तो C++ मानक का कहना व्यवहार अनिर्दिष्ट है [expr.rel]।

मानक अनिर्दिष्ट व्यवहार मतलब है कि यह परिभाषित [defns.unspecified] कार्यान्वयन है कहते हैं।

अपने संकलक संकेत की एक सख्त कमजोर आपको साहचर्य कंटेनरों के साथ किसी भी सूचक का उपयोग कर सकते guaranties हैं।

सबसे compilers स्मृति पतों की तुलना द्वारा सूचक तुलना करते हैं। अधिकांश आर्किटेक्चर पर यह तुलना एक सख्त कमजोर आदेश बनाती है।

इसलिए यह कुंजी के रूप में संकेत का उपयोग करने के लिए सुरक्षित है।

+0

केवल तभी यदि वे एक ही सरणी के तत्वों को इंगित करते हैं। सी ++ मानक std :: कम के लिए मजबूत गारंटी देता है जो आदेशित सहयोगी कंटेनर के लिए डिफ़ॉल्ट है – sellibitze

+0

@ सेलिबिटज़: पॉइंटर्स सरणी से संबंधित नहीं हैं। विभिन्न सरणी के तत्वों के पॉइंटर्स कम तुलनीय हैं। – joke

+1

@joke: नहीं, मानक '<'' के साथ मनमानी पॉइंटर्स की तुलना करने की अनुमति नहीं देता है। – fredoverflow

0

"वे मान्य हो सकते हैं लेकिन नहीं" जवाब मैं दूंगा।

जाहिर है तुलनीयता है कि आप को बढ़ाने का मुद्दा है, लेकिन कारण है कि आप नहीं करना चाहते हैं "वैनिला" संकेत पर संदर्भ प्रबंधन की कमी की वजह है। ऑब्जेक्ट को कंटेनर से हटा दिए बिना हटाया जाना बहुत आसान है, जिसके परिणामस्वरूप अगली बार जब आप इसे एक्सेस करने के लिए एक अवैध पॉइंटर और एक्सेस उल्लंघन करते हैं।

+0

यह आवश्यक नहीं है- unique_ptr या shared_ptr जैसी चीजें अंतर्निहित सूचक पर आधारित तुलनात्मक ऑपरेटरों को अच्छी तरह से प्रदान कर सकती हैं। – Puppy

3

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

यह कड़वी अनुभव की आवाज़ है। मैंने इसे एक बार एक डीबगर परियोजना के साथ किया, जहां मेरे पास सी ++ प्रतीक से भरे कंटेनर थे। जब मुझे प्रतीकों को क्रमबद्ध करने की आवश्यकता होती है, तो मैं अलग-अलग प्रतीकों के साथ समाप्त होता हूं, लेकिन जिनके पास एक ही नाम है (अधिभारित कार्यों को सोचें) और जो कि अन्य सभी सम्मानों में समान थे। इसलिए, इस मामले में मैंने उन्हें प्रतीक वस्तु के पते से अंतिम उपाय के रूप में तुलना की। मैं कई बगों में भाग गया जो स्पष्ट रूप से गैर-निर्धारक थे, जहां गैर-निर्धारणा केवल इस घटना के कारण हुई थी। कभी-कभी समस्याओं को पुन: उत्पन्न करने के लिए 10 या 15 से अधिक प्रयास किए गए। अंत में मैंने पते से छंटाई को खत्म करने के लिए समय निकाला, और इससे मुझे लंबी अवधि में बहुत सारी परेशानी बचाई।

इसके साथ, मैं नहीं कहूंगा कि मैंने हाल ही में यह नहीं किया है। लेकिन हर बार जब मैं ऐसा करता हूं मुझे लगता है कि यह एक गलती है।

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