作者khoguan (Khoguan Phuann)
看板C_and_CPP
標題Re: [問題] map元素的刪除?
時間Fri Jul 1 15:04:59 2005
※ 引述《renderer (rendering)》之銘言:
: ※ 引述《khoguan (Khoguan Phuann)》之銘言:
: : 所謂「標準寫法」其實和原po寫的差不多,只是沒有另外設一個
: : 暫時變數來存下一個 iterator 的值,而是用 postfix ++ 來做。
: : if (/* 符合條件 */)
: : child.erase(i++);
: : else
: : ++i;
: 對喔 iterator++ 是 iterator 自己先加 然後傳一份原來的給 statement 做處理
: 不過在感情上總覺得 它不是掛了嗎 怎麼還有辦法 ++ Orz
您這種感情是有合理的基礎的。;-Q
: 問一個額外的問題 對於 primitive type 如 int
: i++ 編輯器的處理是
: 做完 statement 再加 i 還是
: i 自己先加 但是傳一份原本的 i 給 statement 做處理
i++ 一般簡單的說法都是「先」取值「再」加一。這只是比較容易
解釋,也比較容易聽得懂的說法。其實這兩者並無必然的先後關係。
int i = 10;
i++;
cout << i;
i++ 是一個式子(expression, 而 i++; 多了分號的是 statement),
這整個式子會有一個evaluate後的值,這個值當然還是它原來的值(10),
但是,它另外也會有 side effect,也就是對 i 這個東東做加一的
動作。所以執行到 cout << i; 這個statement時,i 已經變成了 11。
但是加一這個動作到底是在那個精確的時間點完成的呢?
i++; 敘述中的 i++ 是一個 full expression (因為它不是其他
expression 的 subexpression, 若是 i++ + 1; 這個敘述中的 i++
就只是 subexpression)。一個 full expression 後面會有一個
概念上的 sequence point,所有在它之前的 side effect 到達
這個點時,都必須全部完成(而這個點之後的 side effect 則
必須尚未開始)。也就是在上一個 sequence point (A) 與下一個
sequence point (B)之間的所有 side effect 都要在到達 B 時
完成,不過,並不要求得要剛好就在 B 點完成,只要在這段期間內
完成即可,而不硬性規定(unspecified)。這是為了給編譯環境依其
軟硬體特性產生最有效率的機器碼,而容許這種彈性。
至於最上面那個 child.erase(i++); 要進入那個函式之前,也會有
一個 sequence point, 所以 i++ 的 side effect 的部份也會完成,
i 這個 iterator 已經順利的指向下一個 map element 了。而erase()
函式本身接到的引數是原先的 iterator 值(rvalue),將它所對應的
元素刪掉,對 map/set/list 等 node-based container 來說,不會
讓其他的 iterator(包括已經指向下一個 map element 的 i) 也失效,
所以 i 可以繼續安全的使用。
嚴格說來,child.erase(i++); 裡的 ++ 是 overloaded operator function
不過效果還是和內建的 ++ 類似,都會在進入 erase() 之前就完成。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.130.208.168
1F:推 jeunder:真熱心, 快去申請板主啦, 還在這不務正業 :( 61.230.216.76 07/01
※ 編輯: khoguan 來自: 220.130.208.168 (07/01 15:36)
2F:推 khoguan:嗚~~ jeunder你們這些高人都不來帶領大家220.130.208.168 07/01
3F:→ sekya:但是我記得erase正確用法是 i = child.erase( i ); 59.104.35.123 07/01
4F:→ sekya:erase的內部動作,說不定會變整個array都變掉。 59.104.35.123 07/01
5F:→ sekya:增刪各元素的時候,理論上iterator都要重取才對。 59.104.35.123 07/01
6F:推 khoguan:map/set 和 vector/deque 不同220.130.208.168 07/01
7F:推 khoguan:請再看一下 8223 篇220.130.208.168 07/01