2015-12-08 5 views
8

तो, operator[] सीधे यह नहीं कहता कि s[s.size()] स्मृति में s[s.size()-1] के बाद वर्ण होना चाहिए। ऐसा लगता है कि वह दावा करने से बचने के लिए कहा जाता है।क्या `std :: basic_string :: ऑपरेटर []` एक "दूरस्थ" संरक्षित पृष्ठ नल टर्मिनेटर वापस कर सकता है?

लेकिन s.data() बताता है कि s.data()+k == &s[k], और s.data() को एक सूचक वापस करना होगा।

ऊपर CharT और नहीं std::addressof पर & का उपयोग करने का प्रतीयमान मानक दोष की अनदेखी करते हुए कार्यान्वयन वापस जाने के लिए नि: शुल्क है एक अलग CharT (जैसे कि, एक संरक्षित पेज, या रोम में पर एक) s[s.size()] पहली कॉल करने से पहले s.data() करने के लिए ? जहाँ तक मेरा बता सकता हूँ, अगर

:

स्पष्ट होना करने के लिए, (मैं एक अलग स्थिति के बारे में बात कर रहा हूँ जाहिर है यह उस पर एक शून्य के साथ केवल पढ़ने के लिए पृष्ठ पर समाप्त करने के लिए बफर की व्यवस्था कर सकते हैं) s.data() कभी नहीं कहा जाता है (और संकलक इसे साबित कर सकता है), तो s[s.size()] शेष बफर के साथ संगत होने की आवश्यकता नहीं है।

std::addressof(s[s.size()])परिवर्तनs.data() के लिए एक कॉल और कार्यान्वयन के बाद मानकों का अनुपालन करने (जब तक कि s.data()+k == &s[k].data()[] से पहले का मूल्यांकन किया गया है, लेकिन संकलक कि लागू करने के लिए नि: शुल्क है) हो सकता है। या क्या अपरिवर्तनीय आवश्यकताएं हैं जिन्हें मैं नहीं देख सकता हूं?

+0

cppreference स्पष्ट रूप से कहता है कि चूंकि सी ++ 11 'ऑपरेटर []' ठीक उसी तरह व्यवहार करता है जैसे आप डेटा() के लिए वर्णन करते हैं। हालांकि, यह भी उल्लेख करता है कि इस चरित्र को संशोधित नहीं किया जा सकता है। – SergeyA

+1

@ सर्गेयए उपरोक्त शब्द किसी और के आधार पर (वर्तमान में संपादित cppreference अंतिम, कहें) व्याख्या के बजाय (वर्तमान ड्राफ्ट) मानक का मेरा पठन है। यदि आप चाहते हैं, तो मैं सीधे उद्धरण जोड़ सकता हूं, लेकिन उन्हें खोजने में कठिनाई नहीं है (अपना मानक खोलें, 'मूल_स्ट्रिंग' की खोज करें, इंडेक्स से इसे पर जाएं, 'ऑपरेटर ['और' डेटा (वहां से' के लिए खोजें। मैं सोच रहा हूं कि क्या * अन्य * प्रतिबंध हैं जो मुझे याद आया (जैसे मैंने शुरुआत में '.data()' 'और s [s.size()] पर निहित प्रतिबंध को याद किया था।) अधिकांश स्पष्ट (इटेटरेटर्स के आधार पर) डॉन '* s.end() 'यूबी – Yakk

+0

के रूप में लागू नहीं होता है मानक क्या वास्तव में बताता है कि' s.size()] 'अच्छी तरह परिभाषित है और यूबी नहीं है? यह सब के बाद स्ट्रिंग के अंत से पहले है , और किसी भी अन्य कंटेनर के लिए यूबी होगा। एक व्यावहारिक मामले के रूप में प्रत्येक कार्यान्वयन में 'c_str()' द्वारा आवश्यक समाप्ति शून्य को पकड़ने की संभावना है, इसलिए यह शायद एक महत्वपूर्ण बिंदु है। –

उत्तर

1

सी ++ 11 के बाद, std :: स्ट्रिंग को संगत स्मृति में संग्रहीत करने की आवश्यकता है। एक basic_string वस्तु में

चार-तरह की वस्तुओं समीपवर्ती संग्रहीत किया जाएगा: यह (खंड 24.4.1.4) सी ++ 11 मानक से उद्धरण है। यही कारण है, किसी भी basic_string वस्तु रों , पहचान & * (s.begin() + n) == & * s.begin() + n n ऐसी है कि के सभी मानों के लिए पकड़ करेगा < = एन < s.size() ।

ऑपरेटर [] की वापसी मान के बारे में यह कहा गया है कि बोली यह &*(s.begin()+n) (खंड 21.4.5.1) के रूप में देता है एक ही:

* (शुरू() + स्थिति) अगर स्थिति < आकार() । अन्यथा, एक() मान चार्ट के साथ प्रकार चार्ट की एक वस्तु के संदर्भ , जहां किसी चीज़ को संशोधित करने अपरिभाषित व्यवहार

की ओर जाता है देता है तो हम डेटा() में की वापसी मूल्य पर इस उद्धरण है (धारा 24.4.7।1):

एक संकेतक पी ऐसी है कि p + मैं == & ऑपरेटर [] (i) में प्रत्येक मैं के लिए [0, आकार()] ।

तो डेटा उसी तरह देता है जैसे आप & ऑपरेटर [] का उपयोग करेंगे। और & ऑपरेटर का उपयोग करके पुनर्प्राप्त करने के बीच कोई भी मूल्य संगत रूप से संग्रहीत किया जाना चाहिए। तो आप निष्कर्ष निकाल सकते हैं कि दोनों एक सूचक को संगत स्मृति में वापस कर दें। तो यह एक दूरी पृष्ठ पर एक सूचक वापस नहीं करेगा।

ध्यान दें कि यह केवल C++ 11 पर लागू होता है। ऐसी गारंटी सी ++ 11 से पहले मानक द्वारा नहीं बनाई गई थी।

+0

इसे अभी तय किया जाना चाहिए। – Shadowwolf

+1

आपके पहले और दूसरे उद्धरण विशेष रूप से उस मामले को बहिष्कृत करते हैं जहां 'n == s.size()' या 'pos == size()'। – user2357112

+2

@Yakk: दावा का समर्थन करने वाले दूसरे उद्धरण का हिस्सा 'ऑपरेटर []' '* (s.begin() + n) का संदर्भ देता है, जहां उस मामले को शामिल किया गया है जहां' n == s.size() '। – user2357112

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