作者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