विषय पर बढ़ें

अंतिम अद्यतन:2026-10-12

STL इटरेटर अमान्यीकरण

https://stackoverflow.com/questions/6438086/iterator-invalidation-rules-for-c-containers

इंसर्ट (सम्मिलन) सीक्वेंशियल कंटेनर

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

असोसिएटिव कंटेनर

  • [multi]{set,map}: सभी इटरेटर तथा रेफरेंस प्रभावित नहीं होते [23.2.4/9]

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

  • unordered_[multi]{set,map}: रीहैश (rehash) होने पर सभी इटरेटर अमान्य हो जाएँगे, परंतु रेफरेंस प्रभावित नहीं होंगे [23.2.⅝]। यदि इंसर्शन से कंटेनर का आकार z * B से अधिक नहीं होता, तो रीहैश नहीं होगा, जहाँ z अधिकतम लोड फैक्टर है और B वर्तमान बकेट की संख्या है [23.2.5/14]

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

  • stack: अंतर्निहित कंटेनर से इनहेरिट करता है
  • queue: अंतर्निहित कंटेनर से इनहेरिट करता है
  • priority_queue: अंतर्निहित कंटेनर से इनहेरिट करता है

डिलीट (विलोपन) सीक्वेंशियल कंटेनर

  • vector: डिलीशन बिंदु तथा उसके बाद के प्रत्येक इटरेटर तथा रेफरेंस अमान्य हो जाएँगे [23.3.6.5/3]
  • deque: अंतिम एलिमेंट हटाने पर केवल हटाए गए एलिमेंट तथा past-the-end इटरेटर के इटरेटर और रेफरेंस अमान्य होते हैं; पहला एलिमेंट हटाने पर केवल हटाए गए एलिमेंट के इटरेटर तथा रेफरेंस अमान्य होते हैं; कोई अन्य एलिमेंट हटाने पर सभी इटरेटर तथा रेफरेंस (past-the-end इटरेटर सहित) अमान्य हो जाएँगे [23.3.3.4/4]
  • list: केवल हटाए गए एलिमेंट के इटरेटर तथा रेफरेंस अमान्य होते हैं [23.3.5.4/3]
  • forward_list: केवल हटाए गए एलिमेंट के इटरेटर तथा रेफरेंस अमान्य होते हैं (erase_after पर लागू) [23.3.4.5/1]
  • array: (लागू नहीं)

असोसिएटिव कंटेनर

  • [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: (लागू नहीं)

टिप्पणी 1 जब तक स्पष्ट रूप से अन्यथा निर्दिष्ट न हो (चाहे स्पष्ट रूप से या अन्य फंक्शन्स को परिभाषित करने वाले फंक्शन्स के माध्यम से), कंटेनर के मेंबर फंक्शन को कॉल करना या कंटेनर को लाइब्रेरी फंक्शन को तर्क के रूप में पास करना, उस कंटेनर के भीतर के ऑब्जेक्ट्स के इटरेटर को अमान्य नहीं करेगा या उनके मान नहीं बदलेगा। [23.2.1/11]

टिप्पणी 2 कोई भी swap() फंक्शन उन रेफरेंस, पॉइंटर या इटरेटर को अमान्य नहीं करता जो स्वैप किए गए कंटेनरों के एलिमेंट्स की ओर इशारा करते हैं। [नोट: end() इटरेटर किसी एलिमेंट की ओर इशारा नहीं करता, अतः यह अमान्य हो सकता है। — नोट समाप्त] [23.2.1/10]

टिप्पणी 3 उपरोक्त swap() संबंधी चेतावनी के अतिरिक्त, यह स्पष्ट नहीं है कि “end” इटरेटर उपरोक्त प्रत्येक कंटेनर नियम से बंधा है या नहीं; वैसे भी, आपको यह मान लेना चाहिए कि वे बंधे हुए हैं।

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

https://en.cppreference.com/w/cpp/container#Iterator_invalidation

for (auto it = c.begin(); it != c.end(); /*inc in loop*/)
{
   if (it->shouldErase())
   {
         it = c.erase(it);
         continue;
    }
    ...
    ++it;
}
auto is_dead = [](auto const& e) { return !(e->is_alive()); };

std::erase_if(m_entities, is_dead);
std::erase_if(m_entity_map, is_dead);

erase_if or remove_if

https://stackoverflow.com/questions/39019806/using-erase-remove-if-idiom

https://kera.name/articles/2011/06/iterator-invalidation-rules-c0x/

संबंधित विषय

टिप्पणियाँ