2010-06-16 50 views
7

以下代碼無法正常工作。它應該如何正確地完成?如何遍歷STL集合並選擇性地刪除元素?

for (std::set<Color>::iterator i = myColorContainer.begin(); 
      i!=myColorContainer.end(); 
      ++i) 
{ 
    if (*i == Yellow) 
    { 
     DoSomeProccessing(*i); 
     myColorContainer.erase(i); 
    } 
} 

回答

6

你並不需要一個循環爲您選擇處理一組。

std::set<Color>::iterator it = myColorContainer.find(Yellow); 
if (it != it.myColorContainer.end()){ 
    DoSomeProcessing(*it); 
    myColorContainer.erase(it); 
} 
+1

代碼符合標準。我同意@Viktor Sehr這將是從集合中刪除元素的首選方法。但是,該問題詢問如何讓代碼段工作。 – 2010-06-17 09:21:57

+0

@daramarak:我認爲你在編輯代碼的時候回答了(認爲它是我第一篇文章中的std :: vector) – 2010-06-17 09:41:30

7

嘗試:

for(std::set<Color>::iterator it = myColorContainer.begin(); 
    it != myColorContainer.end();) { // note missing it++ 
    if((*it) == Yellow) { 
     DoSomeProcessing(*it); 
     myColorContainer.erase(it++); // post increment (original sent to erase) 
    } 
    else { 
     ++it; // more efficient than it++; 
    } 
} 
+0

這也行不通。您應該再次將擦除的返回值分配給它。 – Patrick 2010-06-16 10:46:14

+0

返回的迭代器是打破標準的微軟特定實現:http://msdn.microsoft.com/en-us/library/8h4a3515%28VS.80%29.aspx。果然,你需要在擦除之後遞增迭代器。 – 2010-06-16 10:53:27

+1

如果您不能使用m $特定的實現並需要使用循環,則此溶劑是完美的。如果你不需要使用循環,Viktor的選擇甚至更好。謝謝你的回答。你一直在幫助很大。 – scippie 2012-03-18 22:54:04

2
for (std::set<Color>::iterator i = myColorContainer.begin(); 
      i!=myColorContainer.end(); /* No i++ */) 
{ 
    if (*i == Yellow) 
    { 
     DoSomeProccessing(*i); 
     std::set<Color>::iterator tmp = i; 
     ++i; 
     myColorContainer.erase(tmp); 
    } 
    else { 
     ++i; 
    } 
} 

一旦你進入下一消息++i可以保證它是有效的 - 這對插入的元素的迭代器,除非該元素 被刪除永遠不會失效的std::set財產。

因此,現在您可以安全地刪除以前的條目。