C++:在迭代中刪除map的成員 首先要清楚一點(diǎn),迭代器相當(dāng)于是容器上的指針,容器可以自己管理內(nèi)
存,因此迭代器可能失效。
如果你在不知情的情況下使用了失效的迭代器,后果是不可預(yù)料的。可能程序立即崩掉,也可能什么事都沒(méi)有發(fā)生。崩掉了算你
幸運(yùn),因?yàn)槟阒辽僦莱隽藛?wèn)題,不然有你受的。
回到正題,我想說(shuō)什么呢?
比如:

程序代碼
map<string,int> theMap;
// add something
to theMap...
for(auto iter1 = theMap.begin(); iter1 !=
theMap.end(); ++iter1)
{
if(iter1->second == xxx)
{
theMap.erase(iter1); //#1
erase the element ??!!
}
}
看樣子貌似非常正常的一
段代碼。在一個(gè)map中尋找值為xxx的項(xiàng)并刪除。
但是實(shí)際上這個(gè)代碼是完全錯(cuò)誤的,會(huì)導(dǎo)致無(wú)法預(yù)料的結(jié)果。
問(wèn)題就在#1處。一
旦你erase了一個(gè)iterator指向的內(nèi)容,這個(gè)iterator就無(wú)效了。
這時(shí)候你再對(duì)這個(gè)iterator做任何操作其結(jié)果都是未定義
的。
那么該怎么辦呢?
還好,對(duì)于map這種以指針構(gòu)建起來(lái)的容器來(lái)說(shuō),可以保證一個(gè)元素刪除了,不影響指向其它元素的迭代器。
因
此就可以這樣做(《C++Standard Library》上建議的正確做法):

程序代碼
for(auto iter1 = theMap.begin(); iter1 !=
theMap.end(); )
{
if(iter1->second == xxx)
{
theMap.erase(iter1++); //#1
}else
{
++iter1;
}
}
這
個(gè)遍歷把迭代器的自增從for頭部中取出,丟到循環(huán)體中去。#1處,iter1++這個(gè)運(yùn)算先自增,但是卻返回了自增前的迭代器的一個(gè)臨時(shí)拷貝。然后這個(gè)
臨時(shí)迭代器指向的內(nèi)容被刪除了,但是iter1本身已經(jīng)自增到下一個(gè)位置了,不受影響。