गाय basic_string
C ++ 11 और बाद में निषिद्ध है?
के बारे में
" क्या मैं सही हूँ कि C ++ 11 गायों के आधारित कार्यान्वयन को स्वीकार नहीं करता है std::string
?
हाँ।
के बारे में
“ यदि ऐसा है, तो क्या यह प्रतिबंध स्पष्ट रूप से नए मानक (जहां) में कहीं है?
लगभग कई कार्यों के लिए लगभग सीधे, O की आवश्यकता होती है एक गाय कार्यान्वयन में स्ट्रिंग डेटा एन ) भौतिक प्रतिलिपि की ।
उदाहरण के लिए, सदस्य कार्यों के लिए
auto operator[](size_type pos) const -> const_reference;
auto operator[](size_type pos) -> reference;
... जो गाय के कार्यान्वयन में स्ट्रिंग मान को साझा करने के लिए स्ट्रिंग डेटा कॉपी करने के लिए ट्रिगर करेगा, मानक मानक C + 11 की आवश्यकता है
C ++ 11 ++21.4.5 / 4 :
" जटिलता: निरंतर समय।
... जो इस तरह के डेटा की नकल के नियम, और इसलिए, गाय।
सी ++ 03 द्वारा समर्थित गाय कार्यान्वयन नहीं इन लगातार जटिलता आवश्यकताओं होने, और से, कुछ प्रतिबंधक शर्तों के तहत, के लिए कॉल की इजाजत दी operator[]()
, at()
, begin()
, rbegin()
, end()
, या rend()
अमान्य संदर्भ, संकेत और iterators स्ट्रिंग आइटम की चर्चा करते हुए के लिए, यानी करने के लिए संभवतः अपने ऊपर लेना एक गाय डेटा कॉपी। यह समर्थन C ++ 11 में हटा दिया गया था।
गाय भी C ++ 11 अमान्य नियमों के माध्यम से निषिद्ध है?
एक अन्य उत्तर में, जो लेखन के समय समाधान के रूप में चुना जाता है, और जो भारी रूप से उखाड़ा जाता है और इसलिए स्पष्ट रूप से माना जाता है, यह माना जाता है कि
" एक गाय के लिए स्ट्रिंग, गैर बुला बुला const
operator[]
एक प्रतिलिपि (और संदर्भों को अमान्य) बनाने की आवश्यकता होगी, जो कि [C ++ 11 quot21.4.1 / 6] के ऊपर [उद्धृत] पैराग्राफ द्वारा अस्वीकृत है। इसलिए, C ++ 11 में गाय का तार होना कानूनी नहीं है।
यह दावा गलत है और दो मुख्य तरीकों से भ्रामक है:
- यह गलत संकेत देता है कि केवल गैर-
const
आइटम एक्सेसरों को एक गाय डेटा कॉपी करने की आवश्यकता है।
लेकिन const
आइटम एक्सेसर्स को भी डेटा कॉपी को ट्रिगर करने की आवश्यकता होती है, क्योंकि वे क्लाइंट कोड को संदर्भ या पॉइंटर्स बनाने की अनुमति देते हैं (जो कि C ++ 11 में) इसे बाद में अमान्य करने की अनुमति नहीं है जो कि गाय डेटा कॉपी को ट्रिगर कर सकते हैं।
- यह गलत तरीके से मानता है कि गाय डेटा कॉपी करने से संदर्भ अमान्य हो सकता है।
लेकिन एक सही कार्यान्वयन में - गाय डेटा कॉपी, स्ट्रिंग मान को साझा करना, एक बिंदु पर किया जाता है इससे पहले कि कोई भी संदर्भ अमान्य हो।
यह देखने के लिए कि C + 11 गाय का एक सही कार्यान्वयन कैसे basic_string
काम करेगा, जब ओ (1) की आवश्यकताएं जो इस अमान्य को अनदेखा करती हैं, एक कार्यान्वयन के बारे में सोचें जहां एक स्ट्रिंग स्वामित्व नीतियों के बीच स्विच कर सकती है। पॉलिसी शेराबल के साथ एक स्ट्रिंग उदाहरण शुरू होता है। इस नीति के सक्रिय होने से कोई बाहरी आइटम संदर्भ नहीं हो सकता है। यह उदाहरण अद्वितीय नीति में परिवर्तन कर सकता है, और ऐसा तब करना चाहिए जब कोई आइटम संदर्भ संभावित रूप से इस तरह के कॉल के साथ बनाया गया हो.c_str()
(कम से कम यदि वह आंतरिक बफ़र को पॉइंटर उत्पन्न करता है) के साथ बनाया गया हो। मूल्य के स्वामित्व को साझा करने वाले कई उदाहरणों के सामान्य मामले में, यह स्ट्रिंग डेटा की प्रतिलिपि बनाता है। अनोखी नीति में परिवर्तन के बाद उदाहरण केवल एक ऑपरेशन द्वारा वापस श्रैले में संक्रमण कर सकता है जो असाइनमेंट जैसे सभी संदर्भों को अमान्य करता है।
तो, जबकि उस उत्तर के निष्कर्ष, कि गाय के तार से इनकार किया जाता है, सही है, जो तर्क दिया गया है वह गलत है और दृढ़ता से भ्रामक है।
मुझे संदेह है कि इस गलतफहमी के कारण C ++ 11 के एनेक्स सी में एक गैर-मानक नोट है:
C ++ 11 3C.2.11 [diff.cpp03.strings], §21.3 के बारे में:
परिवर्तन : basic_string
आवश्यकताएं अब संदर्भ-गणना किए गए स्ट्रिंग्स की अनुमति नहीं देती हैं
Rationale: संदर्भ-गणना स्ट्रिंग्स के साथ अमान्य रूप से भिन्न है। यह परिवर्तन इस अंतर्राष्ट्रीय मानक के लिए व्यवहार (sic) को नियमित करता है।
मूल सुविधा पर प्रभाव: मान्य C ++ 2003 कोड इस अंतर्राष्ट्रीय मानक में अलग तरह से निष्पादित हो सकता है
यहाँ तर्क यह बताता है कि प्राथमिक ने C ++ 03 विशेष गाय समर्थन को हटाने का फैसला क्यों किया। यह तर्क, क्यों , कैसे मानक प्रभावी ढंग से गाय को लागू नहीं करता है। O (1) आवश्यकताओं के माध्यम से मानक विघटित होता है।
संक्षेप में, C ++ 11 अमान्य नियम, गाय के कार्यान्वयन को नियंत्रित नहीं करते हैं std::basic_string
। लेकिन वे यथोचित रूप से कुशल अप्रतिबंधित C ++ 03-शैली के गायन को लागू करते हैं, कम से कम एक g ++ मानक पुस्तकालय कार्यान्वयन में से एक की तरह। विशेष C ++ 03 COW समर्थन ने व्यावहारिक दक्षता की अनुमति दी, विशेष रूप से const
आइटम एक्सेसर्स का उपयोग करते हुए , अमान्य के लिए सूक्ष्म, जटिल नियमों की कीमत पर:
C ++ 03 ++21.3 / 5 जिसमें "पहला कॉल" शामिल है गाय का समर्थन:
" संदर्भ संकेत दिए गए, और iterators एक के तत्वों की चर्चा करते हुए basic_string
अनुक्रम कि के निम्नलिखित का उपयोग करता है के द्वारा अवैध जा सकता है basic_string
वस्तु:
- गैर सदस्य कार्यों के लिए एक तर्क के रूप में swap()
(21.3.7.8), operator>>()
(21.3.7.9), और getline()
(21.3। 7.9)।
- के तर्क के रूप में basic_string::swap()
।
- कॉलिंग data()
और c_str()
सदस्य कार्य।
- गैर कॉलिंग const
सदस्य काम करता है, को छोड़कर operator[]()
, at()
, begin()
, rbegin()
, end()
, और rend()
।
- के रूपों को छोड़कर ऊपर का उपयोग करता है में से किसी के बाद insert()
और erase()
जो गैर करने के लिए iterators लौटने के लिए, पहली कॉल const
सदस्य कार्यों operator[]()
, at()
, begin()
, , याrbegin()
,end()
rend()
।
ये नियम इतने जटिल और सूक्ष्म हैं कि मुझे कई प्रोग्रामर पर संदेह है, यदि कोई हो, तो एक सटीक सारांश दे सकता है। मैं नहीं।
क्या होगा अगर O (1) आवश्यकताओं की अवहेलना की जाए?
यदि उदाहरण के लिए C ++ 11 लगातार समय की आवश्यकताओं की operator[]
अवहेलना की जाती है, तो गाय के लिए basic_string
तकनीकी रूप से संभव हो सकता है, लेकिन इसे लागू करना मुश्किल है।
डेटा की नकल के बिना एक स्ट्रिंग की सामग्री का उपयोग करने वाले संचालन में शामिल हो सकते हैं:
- के माध्यम से संबंध
+
।
- के माध्यम से आउटपुट
<<
।
basic_string
मानक पुस्तकालय कार्यों के तर्क के रूप में उपयोग करना ।
उत्तरार्द्ध क्योंकि मानक पुस्तकालय कार्यान्वयन विशिष्ट ज्ञान और निर्माणों पर भरोसा करने की अनुमति है।
इसके अतिरिक्त एक कार्यान्वयन विभिन्न गैर-मानक कार्यों की पेशकश कर सकता है जो बिना स्ट्रिंग सामग्री को एक्सेस करने के लिए गाय की नकल को ट्रिगर करता है।
एक मुख्य जटिल कारक यह है कि C ++ 11 basic_string
आइटम एक्सेस में डेटा कॉपी को ट्रिगर करना होगा (स्ट्रिंग डेटा को अन-शेयर करना) लेकिन फेंकने के लिए आवश्यक नहीं है , जैसे C ++ 11 §21.4.5 / 3 " फेंकता: कुछ भी नहीं।" और इसलिए यह गाय डेटा की नकल के लिए एक नया बफर बनाने के लिए साधारण गतिशील आवंटन का उपयोग नहीं कर सकता है। इसके आस-पास का एक तरीका एक विशेष ढेर का उपयोग करना है जहां मेमोरी को वास्तव में आवंटित किए बिना आरक्षित किया जा सकता है , और फिर एक स्ट्रिंग मान के लिए प्रत्येक तार्किक संदर्भ के लिए अपेक्षित राशि आरक्षित की जाती है। इस तरह के ढेर में आरक्षण और अन-रिजर्विंग लगातार समय हो सकता है, ओ (1), और उस राशि को आवंटित करना जो पहले से ही आरक्षित है, हो सकती हैnoexcept
। मानक की आवश्यकताओं के अनुपालन के लिए, इस दृष्टिकोण के साथ ऐसा लगता है कि प्रति विशिष्ट आवंटनकर्ता के लिए एक विशेष आरक्षण-आधारित ढेर होने की आवश्यकता होगी।
नोट:
¹ const
आइटम चलाता एक्सेसर को कॉपी एक गाय डेटा क्योंकि यह ग्राहक कोड डेटा है, जो इसे एक बाद डेटा द्वारा रद्द करने के लिए अनुमति नहीं दी जाती जैसे गैर से शुरू हो रहा प्रतिलिपि बनाई जा रही के लिए एक संदर्भ या सूचक प्राप्त करने के लिए अनुमति देता है const
आइटम एक्सेसर।