2012-01-25 15 views
8
Driver::~Driver() 
{ 
    AutoCritSec acsDriverList(m_csDriverList,true); 
    DRIVERLIST::iterator it = m_DriverList.begin(); 
    for(;it!=m_DriverList.end();it++) 
    { 
     if (it->second == this) 
     { 
      m_DriverList.erase(it); 
      it = m_DriverList.begin(); 
     } 
    } 
} 

जब मैं विजुअल स्टूडियो 2003 में अपना प्रोग्राम संकलित करता हूं, तो मेरा प्रोग्राम अच्छा और अच्छा व्यवहार करता है। लेकिन जब मैं 2010 में भी ऐसा ही है, तो थोड़ी देर के अनुप्रयोग को बंद मैंमानचित्र/सेट इटेटरेटर incrementablemap/iterator को incrementable नहीं सेट

Expression:map/set iterator not incrementable 

जैसे कुछ त्रुटि मिलती है और मैं

Expression:"standard c++ library out of range" && 0 

किसी भी एक किसी भी विचार है कि क्या है क्या मिलता है जब मैं इस अनदेखी करने के लिए प्रेस यहां जा रहा है: मैं किसी के द्वारा किसी भी सुझाव के लिए बेहद ऋणी हूं। धन्यवाद और गर्म इच्छाओं के टन।

उत्तर

12

यदि this सूची में एकमात्र तत्व है, तो आप सूची के अंत को खत्म कर देंगे।

सूची से this को हटाने के बाद, आप it = m_DriverList.begin(); रीसेट करते हैं। यह ठीक है। फिर लूप अभिव्यक्ति का मूल्यांकन किया जाता है (i++for कथन से), जो it को सीमा के अंत में उन्नत होने का कारण बनता है।

कंटेनर के अंत से पहले एक पुनरावर्तक को आगे बढ़ाने से प्रोग्राम अपरिभाषित व्यवहार प्रदर्शित कर सकता है। विजुअल सी ++ के हाल के संस्करणों में आपके प्रोग्राम के डीबग बिल्ड में कई सामान्य इटरेटर त्रुटियों की मदद से पता चलता है और उन्हें हल करने में आपकी सहायता के लिए दावे उठाते हैं।

आप पाश अभिव्यक्ति को दूर करने और एक else बयान में ले जाकर समस्या का समाधान कर सकते हैं:

while (it != m_DriverList.end()) 
{ 
    if (it->second == this) 
    { 
     m_DriverList.erase(it); 
     it = m_DriverList.begin(); 
    } 
    else 
    { 
     ++it; 
    } 
} 

हालांकि, हर बार जब आप को दूर एक तत्व नहीं बल्कि बेकार है यात्रा को पुन: प्रारंभ। बजाय इटरेटर कॉल द्वारा लौटाए का उपयोग कर का उपयोग कर erase करने पर विचार करें:

it = m_DriverList.erase(it); 
+0

मिटा का अच्छा सिफारिश/निकालें। इस विशेष मामले में m_DriverList स्पष्ट रूप से जोड़ों का एक कंटेनर है या किसी प्रकार का नक्शा है, क्योंकि परीक्षण उस पर है-> दूसरा। Std :: को हटाने के बजाय इसे ldda या तुलना फ़ंक्शन के साथ std :: remove_if की आवश्यकता होगी। –

+0

यदि कंटेनर एक नक्शा है (प्रश्न शीर्षक, सदस्य 'सेकंड' तक पहुंच) तो मुझे नहीं लगता कि * मिटाएं-निकालें * मुहावरे लागू किया जा सकता है। बेवकूफ आपके पास होने वाले लूप के समान है, लेकिन पुनरावृत्ति को पुनरारंभ करने के बजाय आप प्रतिलिपि को प्रतिलिपि बनाते हैं और फिर वर्तमान स्थिति को मिटा देते हैं। –

+0

@ डेविडरोद्रिगुएज़-ड्राईबीस @ मार्कटाइलर: अच्छा पकड़; मैं परिवर्तनीय नाम में "सूची" द्वारा विचलित था। सी ++ 11 में, 'मिटाएं' पुनरावर्तक को अगले तत्व में लौटाता है (या यदि कोई अगला तत्व नहीं है तो एक-अतीत-अंत तक), और दृश्य C++ 2010 इसका समर्थन करता है। –

6

सही मिटा मुहावरा साहचर्य कंटेनरों के लिए इस प्रकार है:

for (auto it = container.begin(); it != container.end() /* not hoisted */; /* no inc. */) 
{ 
    if (delete_condition) 
    { 
     container.erase(it++); 
    } 
    else 
    { 
     ++it; 
    } 
} 
संबंधित मुद्दे