Iterator अमान्य नियम


543

C ++ कंटेनरों के लिए पुनरावृत्ति अमान्य नियम क्या हैं?

अधिमानतः सारांश सूची प्रारूप में।

(नोट: यह स्टैक ओवरफ्लो के C ++ FAQ के लिए प्रविष्टि माना जाता है । यदि आप इस फॉर्म में FAQ प्रदान करने के विचार की आलोचना करना चाहते हैं, तो मेटा पर पोस्टिंग जो यह सब शुरू करती है वह करने के लिए जगह होगी। उत्तर) उस प्रश्न की निगरानी C ++ चैटरूम में की जाती है , जहाँ पहली बार में FAQ विचार शुरू हुआ है, इसलिए आपका उत्तर उन लोगों द्वारा पढ़ा जाने की संभावना है, जो विचार के साथ आए थे।)


क्या आपके उत्तर के रूप में उत्तर उसी प्रारूप में होने चाहिए?
पीडब्लू

@PW IMO जिसे समरूपता के लिए पसंद किया जाएगा, लेकिन मैं इसे लागू नहीं कर सकता: P
लाइटनेस दौड़ ऑर्बिट

c ++ 20 के बारे में क्या?
वाल्टर

1
@ अल्टर अभी तक मौजूद नहीं है;)
ऑर्बिट में

यह सवाल है, फुतुरमा से लीला को उद्धृत करने के लिए, मूर्ख युगों से, और मेरी विनम्र राय को खुला छोड़ देना चाहिए।
रोमन लुसट्रिक

जवाबों:


110

C ++ 17 (सभी संदर्भ CPP17 के अंतिम कार्य मसौदे से हैं - n4659 )


निवेशन

अनुक्रम कंटेनर

  • vector: कार्यों insert, emplace_back, emplace, push_backकारण पुनः आबंटन अगर नए आकार वर्ष क्षमता से अधिक है। Reallocation अनुक्रम में तत्वों का संदर्भ देते हुए सभी संदर्भों, बिंदुओं और पुनरावृत्तियों को अमान्य करता है। यदि कोई वसूली नहीं होती है, तो सम्मिलन बिंदु से पहले सभी पुनरावृत्तियों और संदर्भ वैध रहते हैं। [२६.३.११.५/१] समारोह के
    संबंध में reserve, पुन: प्राप्ति अनुक्रम में तत्वों का संदर्भ देते हुए सभी संदर्भों, बिंदुओं और पुनरावृत्तियों को अमान्य कर देती है। सम्मिलन के दौरान कोई वसूली नहीं होगी जो किसी कॉल के बाद reserve()उस समय तक होगी जब सम्मिलन वेक्टर के आकार को मूल्य से अधिक कर देगा capacity()। [26.3.11.3/6]

  • deque: मृग के बीच में एक सम्मिलन सभी पुनरावृत्तियों को अमान्य कर देता है और मृग के तत्वों का संदर्भ देता है। मृग के किसी भी छोर पर एक सम्मिलन सभी पुनरावृत्तियों को मृग को अमान्य कर देता है, लेकिन मृग के तत्वों के संदर्भ की वैधता पर कोई प्रभाव नहीं पड़ता है। [26.3.8.4/1]

  • list: पुनरावृत्तियों और संदर्भों की वैधता को प्रभावित नहीं करता है। अगर एक अपवाद को फेंक दिया जाए तो कोई प्रभाव नहीं पड़ता है। [26.3.10.4/1]। , , , , , कार्यों इस नियम के तहत कवर किया जाता है।
    insertemplace_frontemplace_backemplacepush_frontpush_back

  • forward_list: अधिभार में से कोई भी insert_afterपुनरावृत्तियों और संदर्भों की वैधता को प्रभावित नहीं करेगा [26.3.9.5/1]

  • array: एक नियम के रूप में , सरणी के पुनरावृत्तियों को सरणी के जीवनकाल में कभी भी अमान्य नहीं किया जाता है। हालाँकि, एक ध्यान रखना चाहिए, कि स्वैप के दौरान, पुनरावृत्ति उसी सरणी तत्व को इंगित करना जारी रखेगा, और इस प्रकार इसके मूल्य को बदल देगा।

सहयोगी कंटेनर

  • All Associative Containers: insertऔर emplaceसदस्य पुनरावृत्तियों और कंटेनर के संदर्भों को प्रभावित नहीं करेंगे [26.2.6 / 9]

अनियंत्रित एसोसिएटेड कंटेनर

  • All Unordered Associative Containers: रीहैशिंग पुनरावृत्तियों को अमान्य करता है, तत्वों के बीच क्रम में परिवर्तन करता है, और बाल्टी तत्वों में कौन से परिवर्तन दिखाई देते हैं, लेकिन संकेत या तत्वों को संदर्भित नहीं करता है। [26.2.7 / 9] और सदस्यों कंटेनर तत्वों के लिए संदर्भ की वैधता को प्रभावित नहीं करेगा, लेकिन कंटेनर के लिए सभी iterators अमान्य हो सकती है। [26.2.7 / 14] और अगर सदस्यों iterators की वैधता को प्रभावित नहीं करेगा , जहां कंटेनर डालने आपरेशन करने से पहले में तत्वों की संख्या है, डाला तत्वों की संख्या है कंटेनर की बाल्टी गिनती है, और है कंटेनर का अधिकतम लोड कारक। [26.2.7 / 15]
    insertemplace
    insertemplace(N+n) <= z * BNnBz

  • All Unordered Associative Containers: मर्ज ऑपरेशन (उदाहरण के लिए a.merge(a2)) के मामले में, हस्तांतरित तत्वों का जिक्र करने वाले पुनरावृत्तियों और संदर्भित सभी पुनरावृत्तियों को aअमान्य कर दिया जाएगा, लेकिन शेष तत्वों के पुनरावृत्तियों a2मान्य रहेंगे। (तालिका 91 - अनियंत्रित सहयोगी कंटेनर आवश्यकताएं)

कंटेनर एडेप्टर

  • stack: अंतर्निहित कंटेनर से विरासत में मिला
  • queue: अंतर्निहित कंटेनर से विरासत में मिला
  • priority_queue: अंतर्निहित कंटेनर से विरासत में मिला

मिटाना

अनुक्रम कंटेनर

  • vector: फ़ंक्शंस eraseऔर pop_backअमान्य पुनरावृत्तियों और संदर्भों को मिटाए जाने के बिंदु पर या उसके बाद। [26.3.11.5/3]

  • deque: एक मिटा हुआ ऑपरेशन जो dequeअमान्य के अंतिम तत्व को मिटाता है केवल अतीत के अंत का पुनरावृत्ति और सभी पुनरावृत्तियों और मिटाए गए तत्वों को संदर्भित करता है। एक मिटाया गया संचालन जो पहले तत्व को मिटा देता है dequeलेकिन अंतिम तत्व को केवल पुनरावृत्तियों और अवैध मिटाए गए तत्वों को संदर्भित नहीं करता है। एक मिटा हुआ ऑपरेशन जो न तो पहले तत्व को मिटाता है और न ही पिछले तत्व के अंतिम तत्व को dequeअमान्य करता है और सभी पुनरावृत्तियों और सभी तत्वों को संदर्भित करता है deque। [नोट: pop_frontऔर pop_backमिटा रहे हैं संचालन। -एंड नोट] [२६.३./.४/४]

  • list: केवल पुनरावृत्तियों को अमान्य करता है और मिटाए गए तत्वों को संदर्भित करता है। [26.3.10.4/3]। इस पर लागू होता है erase, pop_front, pop_back, clearकाम करता है।
    removeऔर remove_ifसदस्य कार्य: सूची सूची द्वारा निर्दिष्ट सूची के सभी तत्वों को मिटा देता है i, जिसके लिए निम्न स्थितियाँ होती हैं: *i == value, pred(*i) != false। केवल पुनरावृत्तियों को अमान्य करता है और मिटाए गए तत्वों को संदर्भित करता है [26.3.10.5/15]।
    uniqueसदस्य समारोह - सभी को मिटाता है, लेकिन सभी समान तत्वों के समूह के पहले तत्व को पुनरावृत्त द्वारा iश्रेणी में निर्दिष्ट किया जाता है [first + 1, last), जिसके लिए *i == *(i-1)(बिना किसी तर्क के अद्वितीय के संस्करण के लिए) याpred(*i, *(i - 1))(एक विधेय तर्क के साथ अद्वितीय के संस्करण के लिए) रखती है। केवल पुनरावृत्तियों को अमान्य करता है और मिटाए गए तत्वों को संदर्भित करता है। [26.3.10.5/19]

  • forward_list: erase_afterकेवल पुनरावृत्तियों और हटाए गए तत्वों के संदर्भ को अमान्य करेगा। [26.3.9.5/1]।
    removeऔर remove_ifसदस्य फ़ंक्शंस - सूची के सभी तत्वों को एक सूची पुनरावृत्त i द्वारा निर्दिष्ट करता है, जिसके लिए निम्नलिखित स्थितियाँ हैं: *i == value(के लिए remove()), pred(*i)सत्य (के लिए remove_if()) है। केवल पुनरावृत्तियों को अमान्य करता है और मिटाए गए तत्वों को संदर्भित करता है। [26.3.9.6/12]।
    uniqueसदस्य फ़ंक्शन - सभी लेकिन समान तत्वों के हर लगातार समूह से इटर्सेर i द्वारा निर्दिष्ट श्रेणी में पहला तत्व मिटाता है [पहला + 1, अंतिम) जिसके लिए *i == *(i-1)(बिना किसी तर्क pred(*i, *(i - 1))के संस्करण के लिए ) या संस्करण के लिए एक विधेय के साथ तर्क) रखती है। केवल पुनरावृत्तियों को अमान्य करता है और मिटाए गए तत्वों को संदर्भित करता है। [26.3.9.6/16]

  • All Sequence Containers: clearसभी संदर्भों, पॉइंटर्स, और पुनरावृत्तियों को अमान्य करता है जो तत्वों के संदर्भ में है और अतीत के अंत के पुनरावृत्तिक को अमान्य कर सकता है (तालिका 87 - अनुक्रम कंटेनर आवश्यकताओं)। लेकिन forward_list, clearअतीत के अंत पुनरावृत्तियों को अमान्य नहीं करता है। [26.3.9.5/32]

  • All Sequence Containers: assignकंटेनर के तत्वों का संदर्भ देते हुए सभी संदर्भों, बिंदुओं और पुनरावृत्तियों को अमान्य करता है। के लिए vectorऔर dequeभी पास्ट अंत इटरेटर अमान्य हो जाएगा। (तालिका 87 - अनुक्रम कंटेनर आवश्यकताएं)

सहयोगी कंटेनर

  • All Associative Containers: eraseसदस्य केवल पुनरावृत्तियों को और मिटाए गए तत्वों को संदर्भित करेंगे [26.2.6 / 9]

  • All Associative Containers: extractसदस्य हटाए गए तत्व को केवल पुनरावृत्तियों को अमान्य करते हैं; हटाए गए तत्व के संकेत और संदर्भ वैध रहते हैं [26.2.6 / 10]

कंटेनर एडेप्टर

  • stack: अंतर्निहित कंटेनर से विरासत में मिला
  • queue: अंतर्निहित कंटेनर से विरासत में मिला
  • priority_queue: अंतर्निहित कंटेनर से विरासत में मिला

इटैलर अमान्य से संबंधित सामान्य कंटेनर आवश्यकताएं:

  • जब तक अन्यथा निर्दिष्ट नहीं किया जाता है (या तो स्पष्ट रूप से या अन्य कार्यों के संदर्भ में एक फ़ंक्शन को परिभाषित करके), कंटेनर सदस्य फ़ंक्शन को लागू करना या किसी लाइब्रेरी फ़ंक्शन के तर्क के रूप में कंटेनर को पारित करना पुनरावृत्तियों को अमान्य नहीं करेगा, या इस आइटम के मानों को बदल नहीं सकता है; । [26.2.1 / 12]

  • कोई swap()भी फ़ंक्शन किसी भी संदर्भ, पॉइंटर्स, या पुनरावृत्तियों को अमान्य नहीं करता है, जिसमें कंटेनरों के तत्वों की अदला-बदली की जाती है। [नोट: अंत () इटेटर किसी भी तत्व को संदर्भित नहीं करता है, इसलिए इसे अमान्य किया जा सकता है। -एड नोट] [२६.२.१ / (११.६)]

उपरोक्त आवश्यकताओं के उदाहरण के रूप में:

  • transformएल्गोरिथ्म: opऔर binary_opफ़ंक्शन पुनरावृत्तियों या सबरेंज को अमान्य नहीं करेंगे, या [28.6.4 / 1] श्रेणी में तत्वों को संशोधित करेंगे।

  • accumulateएल्गोरिथ्म: रेंज में [पहला, अंतिम], binary_opन तो तत्वों को संशोधित करेगा और न ही पुनरावृत्तियों या सबरेंज को [29.8.2 / 1] अमान्य करेगा

  • reduceएल्गोरिथ्म: बाइनरी_ओप न तो पुनरावृत्तियों या सबरेंजों को अमान्य करेगा, और न ही [प्रथम, अंतिम] श्रेणी में तत्वों को संशोधित करेगा। [29.8.3 / 5]

और इसी तरह...


7
ओह पीडब्लू यू हीरो!
ऑर्बिट

2
@LightnessRacesinOrbit: अपने मूल उत्तर प्रारूप के अनुसार करने की कोशिश की। :)
पीडब्लू

1
क्या हमारे पास इसके लिए लिस्टिंग भी हो सकती है std::string? मुझे लगता है कि यह std::vectorSSO के कारण से अलग है
sp2danny

1
@ sp2danny: SSO के कारण, stringऊपर सूचीबद्ध दूसरी सामान्य आवश्यकता विफल हो जाती है। इसलिए मैंने इसे शामिल नहीं किया। पिछली FAQ प्रविष्टियों के समान पैटर्न से चिपके रहने का प्रयास किया।
पीडब्लू

@LightnessRaceswithMonica कड़ी मेहनत के लिए धन्यवाद दोस्तों। मेरे पास एक प्रश्न है जो मुझे दिनों तक भ्रमित करता है। इन संदर्भों पर "अमान्य" क्या मतलब है? क्या इसका मतलब है "invalidated" can mean "no longer points to what it used to", not just "may not point to any valid element"कि @ मर्सल क्लो इस उत्तर में वर्णित है ? या यह केवल 2 में से केवल 1 संकेत देता है?
रिक

410

C ++ 03 (स्रोत: Iterator अमान्य नियम (C ++ 03) )


निवेशन

अनुक्रम कंटेनर

  • vector: सम्मिलन के बिंदु से पहले सभी पुनरावृत्तियों और संदर्भों को अप्रभावित किया जाता है, जब तक कि नए कंटेनर का आकार पिछली क्षमता से अधिक न हो (जिस स्थिति में सभी पुनरावृत्तियों और संदर्भ अमान्य हैं) [23.2.4.3/1]
  • deque: सभी पुनरावृत्तियों और संदर्भों को अमान्य कर दिया जाता है, जब तक कि सम्मिलित सदस्य छल के अंत (सामने या पीछे) पर न हो (जिस स्थिति में सभी पुनरावृत्तियों को अमान्य कर दिया जाता है, लेकिन तत्वों के संदर्भ अप्रभावित हैं) [23.2.1.3/1]
  • list: सभी पुनरावृत्तियों और संदर्भ अप्रभावित [23.2.2.3/1]

सहयोगी कंटेनर

  • [multi]{set,map}: सभी पुनरावृत्तियों और संदर्भ अप्रभावित [23.1.2 / 8]

कंटेनर एडेप्टर

  • stack: अंतर्निहित कंटेनर से विरासत में मिला
  • queue: अंतर्निहित कंटेनर से विरासत में मिला
  • priority_queue: अंतर्निहित कंटेनर से विरासत में मिला

मिटाना

अनुक्रम कंटेनर

  • vector: मिटा के बिंदु के बाद हर पुनरावृत्ति और संदर्भ अमान्य है [23.2.4.3/3]
  • deque: सभी पुनरावृत्तियों और संदर्भों को अमान्य कर दिया जाता है, जब तक कि मिटाए गए सदस्य छल के अंत (सामने या पीछे) पर न हों (जिस स्थिति में केवल पुनरावृत्तियों और मिटाए गए सदस्यों के संदर्भ अमान्य हैं) [23.2.1.3/4]
  • list: केवल पुनरावृत्तियों और मिटाए गए तत्व के संदर्भ अमान्य हैं [23.2.2.3/3]

सहयोगी कंटेनर

  • [multi]{set,map}: केवल पुनरावृत्तियों और मिटाए गए तत्वों के संदर्भ अमान्य हैं [23.1.2 / 8]

कंटेनर एडेप्टर

  • stack: अंतर्निहित कंटेनर से विरासत में मिला
  • queue: अंतर्निहित कंटेनर से विरासत में मिला
  • priority_queue: अंतर्निहित कंटेनर से विरासत में मिला

पुन: आकार देने

  • vector: डालने के अनुसार / मिटा [23.2.4.2/6]
  • deque: डालने के अनुसार / मिटाएँ [२३.२.१.२/१]
  • list: डालने के अनुसार / मिटाएँ [२३.२.२.२/१]

नोट 1

जब तक अन्यथा निर्दिष्ट नहीं किया जाता है (या तो स्पष्ट रूप से या अन्य कार्यों के संदर्भ में एक फ़ंक्शन को परिभाषित करके), कंटेनर सदस्य फ़ंक्शन को लागू करना या किसी लाइब्रेरी फ़ंक्शन के तर्क के रूप में कंटेनर को पारित करना पुनरावृत्तियों को अमान्य नहीं करेगा , या इस आइटम के मानों को बदल नहीं सकता है; । [23.1 / 11]

नोट 2

यह C ++ 2003 में स्पष्ट नहीं है कि क्या "अंत" चलने वाले उपरोक्त नियमों के अधीन हैं ; वैसे भी, आपको यह मान लेना चाहिए कि वे हैं (जैसा कि व्यवहार में ऐसा है)।

नोट 3

बिंदुओं के अमान्यकरण के नियम संदर्भों के अमान्यकरण के नियम के रूप में हैं।


5
अच्छा विचार है, केवल टिप्पणी करने के लिए: मुझे लगता है कि साहचर्य कंटेनरों को एक ही पंक्ति में एक साथ मोड़ा जा सकता है, और यह तब हो सकता है जब अनियंत्रित साहचर्य की एक और पंक्ति जोड़ दी जाए ... हालांकि मुझे यकीन नहीं है कि पुनर्वितरित भाग कैसे हो सकता है डालने / मिटाने पर मैप किया जाता है, क्या आपको यह जांचने का कोई तरीका पता है कि रिहैस को ट्रिगर किया जाएगा या नहीं?
मैथ्यू एम।

1
IIRC, कहीं न कहीं यह युक्ति कहती है कि अंतिम पुनरावृती "कंटेनर के भीतर की वस्तुओं" के लिए एक पुनरावृत्ति नहीं है। मुझे आश्चर्य है कि वे गारंटी प्रत्येक मामले में अंतिम पुनरावृत्ति के लिए कैसे देखते हैं?
जोहान्स स्काउब - १२:०५ पर

1
@MuhammadAnnaqeeb: इस सवाल का जवाब वैसे यह स्पष्ट, जैसा कि मैंने एक शॉर्टकट ले लिया नहीं है, लेकिन इरादा कहना है कि आकार बदलने है है प्रविष्टि / विलोपन, जैसे कि एक पुनः आबंटन की आवश्यकता है, तो आप मिटाने का काम के रूप में ही विचार कर सकते हैं कि फिर सभी प्रभावित तत्वों को फिर से सम्मिलित करना। उत्तर के उस खंड में निश्चित रूप से सुधार किया जा सकता है।
ऑर्बिट

1
@ यक: लेकिन यह नहीं है; उद्धृत मानक पाठ देखें। ऐसा लगता है कि हालांकि C ++ 11 में तय किया गया था। :)
को ऑर्बिट में लाइटनेस दौड़

1
@metamorphosis: गैर-सन्निहित ब्लॉक में डेटा संग्रहीत करता है। शुरुआत या अंत में सम्मिलित करने से एक नया ब्लॉक आवंटित हो सकता है, लेकिन यह पिछले तत्वों के आसपास कभी नहीं चलता है, इसलिए संकेत मान्य रहते हैं। लेकिन नया ब्लॉक आवंटित होने पर अगले / पिछले तत्व में जाने के नियम बदल जाते हैं, इसलिए पुनरावृत्तियों को अमान्य कर दिया जाता है।
निक मैट्टो

357

C ++ 11 (स्रोत: Iterator अमान्य नियम (C ++ 0x) )


निवेशन

अनुक्रम कंटेनर

  • vector: सम्मिलन के बिंदु से पहले सभी पुनरावृत्तियों और संदर्भों को अप्रभावित किया जाता है, जब तक कि नए कंटेनर का आकार पिछली क्षमता से अधिक न हो (जिस स्थिति में सभी पुनरावृत्तियों और संदर्भ अमान्य हैं) [23.3.6.5/1]
  • deque: सभी पुनरावृत्तियों और संदर्भों को अमान्य कर दिया जाता है, जब तक कि सम्मिलित सदस्य छल के अंत (सामने या पीछे) पर न हो (जिस स्थिति में सभी पुनरावृत्तियों को अमान्य कर दिया जाता है, लेकिन तत्वों के संदर्भ अप्रभावित हैं) [23.3.3.4/1]
  • list: सभी पुनरावृत्तियों और संदर्भ अप्रभावित [23.3.5.4/1]
  • forward_list: सभी पुनरावृत्तियों और संदर्भ अप्रभावित (पर लागू होता है insert_after) [23.3.4.5/1]
  • array: (n / a)

सहयोगी कंटेनर

  • [multi]{set,map}: सभी पुनरावृत्तियों और संदर्भ अप्रभावित [23.2.4 / 9]

अनसोल्ड एसोसिएटेड कंटेनर

  • unordered_[multi]{set,map}: पुनरावृत्ति होने पर सभी पुनरावृत्तियों को अमान्य कर दिया जाता है, लेकिन अप्रभावित [23.2.5 / 8]। पुनरावृत्ति तब नहीं होती है जब सम्मिलन कंटेनर के आकार से अधिक नहीं होता है z * Bजहां zअधिकतम लोड कारक है और Bबाल्टी की वर्तमान संख्या है। [23.2.5 / 14]

कंटेनर एडेप्टर

  • stack: अंतर्निहित कंटेनर से विरासत में मिला
  • queue: अंतर्निहित कंटेनर से विरासत में मिला
  • priority_queue: अंतर्निहित कंटेनर से विरासत में मिला

मिटाना

अनुक्रम कंटेनर

  • vector: मिटाए जाने के बिंदु पर या उसके बाद हर पुनरावृत्ति और संदर्भ को अमान्य कर दिया जाता है [23.3.6.5/3]
  • deque: अंतिम तत्व को मिटाना केवल पुनरावृत्तियों को अमान्य करता है और मिटाए गए तत्वों और अतीत के अंत के पुनरावृत्ति को संदर्भित करता है; पहले तत्व को मिटाना केवल पुनरावृत्तियों को अमान्य करता है और मिटाए गए तत्वों को संदर्भित करता है; किसी भी अन्य तत्वों को मिटाने से सभी पुनरावृत्तियों और संदर्भों को अमान्य कर दिया जाता है (अतीत के अंत वाले पुनरावृत्ति सहित) [23.3.3/4-4]
  • list: केवल पुनरावृत्तियों और मिटाए गए तत्व के संदर्भ को अमान्य कर दिया जाता है [23.3.5.4/3]
  • forward_list: केवल पुनरावृत्तियों और मिटाए गए तत्व का संदर्भ अमान्य है (लागू होता है erase_after) [23.3.4.5/1]
  • array: (n / a)

सहयोगी कंटेनर

  • [multi]{set,map}: केवल पुनरावृत्तियों और मिटाए गए तत्वों के संदर्भ अमान्य हैं [23.2.4 / 9]

अनियंत्रित साहचर्य कंटेनर

  • unordered_[multi]{set,map}: केवल पुनरावृत्तियों और मिटाए गए तत्वों के संदर्भ अमान्य हैं [23.2.5 / 13]

कंटेनर एडेप्टर

  • stack: अंतर्निहित कंटेनर से विरासत में मिला
  • queue: अंतर्निहित कंटेनर से विरासत में मिला
  • priority_queue: अंतर्निहित कंटेनर से विरासत में मिला

पुन: आकार देने

  • vector: इंसर्ट / इरेज़ के अनुसार [23.3.6.5/12]
  • deque: डालने के अनुसार / मिटा [23.3.3.3/3]
  • list: इंसर्ट / इरेज़ के अनुसार [23.3.5.3/1]
  • forward_list: इंसर्ट / इरेज़ के अनुसार [23.3.4.5/25]
  • array: (n / a)

नोट 1

जब तक अन्यथा निर्दिष्ट नहीं किया जाता है (या तो स्पष्ट रूप से या अन्य कार्यों के संदर्भ में एक फ़ंक्शन को परिभाषित करके), कंटेनर सदस्य फ़ंक्शन को लागू करना या किसी लाइब्रेरी फ़ंक्शन के तर्क के रूप में कंटेनर को पारित करना पुनरावृत्तियों को अमान्य नहीं करेगा , या इस आइटम के मानों को बदल नहीं सकता है; । [23.2.1 / 11]

नोट 2

कोई स्वैप () फ़ंक्शन किसी भी संदर्भ, पॉइंटर्स, या पुनरावृत्तियों को अमान्य करता है जो कंटेनरों की अदला-बदली के तत्वों का उल्लेख करते हैं। [नोट: अंत () इटेटर किसी भी तत्व को संदर्भित नहीं करता है, इसलिए इसे अमान्य किया जा सकता है । -एंड नोट] [२३.२.१ / १०]

नोट 3

उपरोक्त कैविएट के अलावा swap(), यह स्पष्ट नहीं है कि "अंत" पुनरावृत्तियों उपरोक्त सूचीबद्ध प्रति-कंटेनर नियमों के अधीन हैं या नहीं ; आपको, वैसे भी, मान लेना चाहिए कि वे हैं।

नोट 4

vectorऔर सभी अनियंत्रित साहचर्य कंटेनर समर्थन करते हैं reserve(n)जो गारंटी देता है कि कंटेनर का आकार बढ़ने तक कोई भी स्वचालित आकार कम से कम नहीं होगा nअनियोजित एसोसिएटेड कंटेनरों के साथ सावधानी बरती जानी चाहिए क्योंकि भविष्य के प्रस्ताव में न्यूनतम लोड कारक के विनिर्देशन की अनुमति होगी, जो न्यूनतम संचालन के insertबाद eraseकंटेनर के आकार को कम से कम करने के लिए पर्याप्त संचालन के बाद फिर से होने की अनुमति देगा ; गारंटी को एक के बाद संभावित शून्य माना जाना चाहिए erase


इसके अलावा swap(), कॉपी / चाल असाइनमेंट पर पुनरावृत्ति वैधता के लिए क्या नियम हैं?
अलविदा

@LightnessRacesinOrbit: सम्मिलन, मिटाना, आकार बदलना और स्वैप की तरह, कॉपी / मूव असाइनमेंट भी std :: वेक्टर के सदस्य कार्य हैं, इसलिए मुझे लगता है कि आप उनके लिए पुनरावृत्ति वैधता के नियम भी प्रदान कर सकते हैं।
गुडबायरा

@goodbyeera: आपका मतलब है कि एक तत्व को कॉपी / स्थानांतरित करें? यह किसी भी पुनरावृत्तियों को प्रभावित नहीं करेगा। क्यों होगा? आप नोट 1 से ऊपर मार रहे हैं ।
ऑर्बिट

1
मुझे लगता है कि मैंने एक त्रुटि की है, क्योंकि std::basic_stringऐसा प्रतीत नहीं होता है कि एक कंटेनर के रूप में गिना जाता है, और निश्चित रूप से उस मानक के अनुभाग में कंटेनर नहीं है जो नोट पर लागू होता है। फिर भी, यह कहाँ कहता है कि एसएसओ को अस्वीकृत किया गया है (मुझे पता है कि गाय है)?
Deduplicator

2
क्या ये नियम C ++ 14 में समान हैं? C ++ 17 (अब तक ज्ञात है)?
ईनपोकलम

40

यह संभवतः जोड़ने योग्य है कि किसी भी प्रकार ( std::back_insert_iterator,, ) का एक सम्मिलित इट्रेटर तब तक वैध बने रहने की गारंटी है std::front_insert_iterator, std::insert_iteratorजब तक कि सभी पुनरावृत्तियां इस पुनरावृत्ति के माध्यम से नहीं की जाती हैं और कोई अन्य स्वतंत्र इटेरेटर-अमान्य घटना नहीं होती है।

उदाहरण के लिए, जब आप std::vectorउपयोग करके सम्मिलन संचालन की एक श्रृंखला का प्रदर्शन कर रहे हैंstd::insert_iterator यह संभव है कि ये सम्मिलन वेक्टर पुनः प्राप्ति को ट्रिगर करेंगे, जो सभी पुनरावृत्तियों को उस वेक्टर में "बिंदु" को अमान्य कर देगा। हालांकि, विचाराधीन इंसर्ट डालने वाले को वैध बने रहने की गारंटी दी जाती है, अर्थात आप सुरक्षित रूप से आवेषण का क्रम जारी रख सकते हैं। सदिश reallocation को ट्रिगर करने के बारे में चिंता करने की कोई आवश्यकता नहीं है।

यह, फिर से, केवल सम्मिलित पुनरावृत्ति के माध्यम से किए गए सम्मिलन पर लागू होता है। यदि कंटेनर पर कुछ स्वतंत्र कार्रवाई द्वारा इटेरेटर-अमान्य घटना को ट्रिगर किया जाता है, तो इंसर्ट डालने वाला सामान्य नियमों के अनुसार अमान्य हो जाता है।

उदाहरण के लिए, यह कोड

std::vector<int> v(10);
std::vector<int>::iterator it = v.begin() + 5;
std::insert_iterator<std::vector<int> > it_ins(v, it);

for (unsigned n = 20; n > 0; --n)
  *it_ins++ = rand();

वेक्टर में सम्मिलन के एक वैध अनुक्रम को करने के लिए गारंटी दी जाती है, भले ही वेक्टर इस प्रक्रिया के बीच में कहीं पर फिर से स्थापित करने का "निर्णय" करता है। Iterator itस्पष्ट रूप से अमान्य हो जाएगा, लेकिन it_insवैध बना रहेगा।


22

चूँकि यह प्रश्न इतने सारे मतों को आकर्षित करता है और एक सामान्य प्रश्न बनता है, इसलिए मुझे लगता है कि C ++ 03 और C ++ 11 के बीच एक महत्वपूर्ण अंतर का उल्लेख करने के लिए एक अलग उत्तर लिखना बेहतर होगा std::vector। पुनरावृत्तियों की वैधता और संदर्भ के संदर्भ में reserve()और capacity(), जो कि सबसे अधिक उत्तर दिया गया नोटिस नोटिस करने में विफल रहा।

C ++ 03:

Reallocation अनुक्रम में तत्वों का संदर्भ देते हुए सभी संदर्भों, बिंदुओं और पुनरावृत्तियों को अमान्य करता है। यह गारंटी दी जाती है कि कॉल करने के बाद होने वाले सम्मिलन के दौरान कोई भी रियलाइजेशन नहीं होता है (उस समय तक) जब तक कोई प्रविष्टि वेक्टर के आकार को आरक्षित किए गए सबसे हाल के कॉल से निर्दिष्ट आकार से अधिक कर देगा ()

सी ++ 11:

Reallocation अनुक्रम में तत्वों का संदर्भ देते हुए सभी संदर्भों, बिंदुओं और पुनरावृत्तियों को अमान्य करता है। यह इस बात की गारंटी है कि किसी कॉल के बाद होने वाले सम्मिलन के दौरान कोई भी रियलाइजेशन नहीं होता है (रिज़र्वेशन के बाद) जब तक कि इंसर्शन क्षमता के मान से अधिक वेक्टर का आकार बना देगा ()

इसलिए C ++ 03 में, यह " unless the new container size is greater than the previous capacity (in which case all iterators and references are invalidated)" नहीं है जैसा कि दूसरे उत्तर में बताया गया है, इसके बजाय, यह " greater than the size specified in the most recent call to reserve()" होना चाहिए । यह एक बात है कि C ++ 03 C ++ 11 से भिन्न है। C ++ 03 में, एक बार insert()वेक्टर का आकार पिछली reserve()कॉल में निर्दिष्ट मूल्य तक पहुंचने का कारण बनता है (जो कि वर्तमान capacity()से भी छोटा reserve()हो सकता है क्योंकि इससे बड़ा परिणाम हो सकता है capacity()), किसी भी बाद में insert()वसूली और अमान्य हो सकता है सभी पुनरावृत्तियों और संदर्भ। C ++ 11 में, ऐसा नहीं होगा और आप हमेशा capacity()यह निश्चितता के साथ जान सकते हैं कि अगला वास्तविककरण आकार के बाईपास से पहले नहीं होगा capacity()

अंत में, यदि आप C ++ 03 वेक्टर के साथ काम कर रहे हैं और आप यह सुनिश्चित करना चाहते हैं कि जब आप प्रविष्टि करते हैं तो एक रियलाइजेशन नहीं होगा, तो यह उस तर्क का मूल्य है जो आपने पहले पारित किया था reserve()कि आपको इसके विरुद्ध आकार की जांच करनी चाहिए, नहीं किसी कॉल का रिटर्न वैल्यू capacity(), अन्यथा आप अपने आप को " समय से पहले " रियलकेशन पर आश्चर्यचकित कर सकते हैं ।


14
हालांकि, मैं किसी भी कंपाइलर को गोली मार दूंगा जिसने मेरे साथ ऐसा किया है, और भूमि में कोई जूरी मुझे दोषी नहीं ठहराएगा।
यक्क - एडम नेवरामोंट

9
मैंने इसे "नोटिस करने में विफल" नहीं किया; यह C ++ 03 में एक संपादकीय त्रुटि थी जिसे C ++ 11 में ठीक किया गया था। कोई भी मुख्यधारा संकलक त्रुटि का लाभ नहीं उठाता है।
ऑर्बिट

1
@ मुझे लगता है कि जीसीसी पहले से ही ऐसी स्थितियों में पुनरावृत्तियों को अमान्य करता है।
श्रीवत्सआर

2

यहाँ cppreference.com से एक अच्छी सारिणी है :

यहाँ छवि विवरण दर्ज करें

यहां, सम्मिलन किसी भी विधि को संदर्भित करता है जो कंटेनर में एक या एक से अधिक तत्व जोड़ता है और मिटाना किसी भी विधि को संदर्भित करता है जो कंटेनर से एक या अधिक तत्वों को निकालता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.