﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-lucky_fox-最新评论</title><link>http://www.cppblog.com/lucky_fox/CommentsRSS.aspx</link><description /><language>zh-cn</language><pubDate>Mon, 13 Feb 2006 02:43:36 GMT</pubDate><lastBuildDate>Mon, 13 Feb 2006 02:43:36 GMT</lastBuildDate><generator>cnblogs</generator><item><title>re: 关于list容器的问题！</title><link>http://www.cppblog.com/lucky_fox/archive/2006/03/12/3228.html#4059</link><dc:creator>lucky_fox</dc:creator><author>lucky_fox</author><pubDate>Sun, 12 Mar 2006 15:18:00 GMT</pubDate><guid>http://www.cppblog.com/lucky_fox/archive/2006/03/12/3228.html#4059</guid><description><![CDATA[比较好的解决方法是考虑利用erase的返回值来作为删除后下一元素的位置！<br>int ia[]={0,1,1,2,3,5,8,13,21,34,55,89,144};<br>  list&lt;int&gt; ilist(ia,ia+12);<br>  list&lt;int&gt;::iterator il_iter=ilist.begin();<br>   for(int i=1;il_iter!=ilist.end();i++)<br>  {<br>  <br>    if(i%2!=0)<br>    {<br>     il_iter = ilist.erase(il_iter);<br>     }<br>    else<br>    {<br>      il_iter++;<br>    }<br>  <br>  }<br>  <br>  il_iter=ilist.begin();<br>  <br>  for(;il_iter!=ilist.end();il_iter++)<br>  {<br>    cout&lt;&lt;*il_iter&lt;&lt;&quot;\n&quot;;<br>  }<br><br>return 0;<img src ="http://www.cppblog.com/lucky_fox/aggbug/4059.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lucky_fox/" target="_blank">lucky_fox</a> 2006-03-12 23:18 <a href="http://www.cppblog.com/lucky_fox/archive/2006/03/12/3228.html#4059#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>re: 关于list容器的问题！</title><link>http://www.cppblog.com/lucky_fox/archive/2006/03/11/3228.html#3991</link><dc:creator>lucky_fox</dc:creator><author>lucky_fox</author><pubDate>Fri, 10 Mar 2006 16:06:00 GMT</pubDate><guid>http://www.cppblog.com/lucky_fox/archive/2006/03/11/3228.html#3991</guid><description><![CDATA[这样好像又可以了<br>	int ia[]={0,1,1,2,3,5,8,13,21,34,55,89,144,233};<br>	list&lt;int&gt; ilist(ia,ia+14);<br>	list&lt;int&gt;::iterator il_iter=ilist.begin();<br>	<br>	int ct=ilist.size();<br>	for(int i=0;i&lt;ct;i+=2)<br>	{<br><br>		il_iter=ilist.erase(il_iter); <br>		if(il_iter!=ilist.end())<br>			il_iter++; <br>	}<br>	il_iter=ilist.begin();<br>	for(;il_iter!=ilist.end();il_iter++)<br>		cout&lt;&lt;*il_iter&lt;&lt;endl;<img src ="http://www.cppblog.com/lucky_fox/aggbug/3991.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lucky_fox/" target="_blank">lucky_fox</a> 2006-03-11 00:06 <a href="http://www.cppblog.com/lucky_fox/archive/2006/03/11/3228.html#3991#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>re: 关于list容器的问题！</title><link>http://www.cppblog.com/lucky_fox/archive/2006/03/10/3228.html#3960</link><dc:creator>lucky_fox</dc:creator><author>lucky_fox</author><pubDate>Fri, 10 Mar 2006 03:11:00 GMT</pubDate><guid>http://www.cppblog.com/lucky_fox/archive/2006/03/10/3228.html#3960</guid><description><![CDATA[根据上面的提示对程序做了如下的修改：<br>#include &lt;iostream&gt;<br>#include &lt;vector&gt;<br>#include &lt;list&gt;<br>#include &lt;string&gt;<br>#include &lt;algorithm&gt;<br>#include &lt;functional&gt;<br>using namespace std;<br><br>int main()<br>{<br><br>	int ia[]={0,1,1,2,3,5,8,13,21,34,55,89};<br>	list&lt;int&gt; ilist(ia,ia+12);<br>	list&lt;int&gt;::iterator il_iter=ilist.begin();<br>	ilist.remove_if(binder2nd(modulus&lt;int&gt;(),2));<br>	for(;il_iter!=ilist.end();il_iter++)<br>		cout&lt;&lt;*il_iter&lt;&lt;&quot;\n&quot;;<br>	return 0;<br>}<br>但是编译有错<br>error C2955: 'binder2nd' : use of class template requires template argument list<br>该如何更正呢？<img src ="http://www.cppblog.com/lucky_fox/aggbug/3960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lucky_fox/" target="_blank">lucky_fox</a> 2006-03-10 11:11 <a href="http://www.cppblog.com/lucky_fox/archive/2006/03/10/3228.html#3960#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>re: 关于list容器的问题！</title><link>http://www.cppblog.com/lucky_fox/archive/2006/03/03/3228.html#3676</link><dc:creator>lucky_fox</dc:creator><author>lucky_fox</author><pubDate>Fri, 03 Mar 2006 04:09:00 GMT</pubDate><guid>http://www.cppblog.com/lucky_fox/archive/2006/03/03/3228.html#3676</guid><description><![CDATA[●vector 的元素删除<br><br>话头从 container 的元素删除说起。jyhuang 观察到「如果 vector 或 list<br>的最後一个元素符合删除条件，程式会有问题」。他给我这样一个片段：<br><br>template &lt;typename T&gt;<br>void print_elements(T elem) { cout &lt;&lt; elem &lt;&lt; &quot; &quot;; }<br><br>void (*pfi)(int) = print_elements; // 函式指标，做为 function object 用<br>...<br>int ia[7] = {0,1,2,3,4,5,6};<br>vector&lt;int&gt; ivec(ia, ia+7);<br>for_each(ivec.begin(), ivec.end(), pfi); // 0 1 2 3 4 5 6<br><br>for (vector&lt;int&gt;::iterator it = ivec.begin(); it != ivec.end(); it++) {<br>  if (*it % 2) // 把奇数去掉<br>    ivec.erase(it);<br>}<br>for_each(ivec.begin(), ivec.end(), pfi); // 0 2 4 6 正确！<br><br><br>如果把 array 和 vector 的初值改为：<br><br>int ia[8] = {0,1,2,3,4,5,6,7};<br>vector&lt;int&gt; ivec(ia, ia+8);<br><br>则上述程式会当掉。<br><br><br>●I don't think so...<br><br>我不相信 STL 会有这麽差劲的表现。所以多做了几次测试如下。<br><br>(1) 把 array 和 vector 的初值改为：<br><br>int ia[7] = {0,1,2,3,4,5,7};<br>vector&lt;int&gt; ivec(ia, ia+7);<br><br>程式结果为 0 2 4 7。结果不对，但不会当掉。<br><br>(2) 把 array 和 vector 的初值改为：<br><br>int ia[7] = {0,1,3,5,7,9,7};<br>vector&lt;int&gt; ivec(ia, ia+7);<br><br>程式结果为 0 3 7 7。错得离谱，但不会当掉。<br><br>(3) 把 array 和 vector 的初值改为：<br><br>int ia[7] = {0,2,4,6,0,4,7};<br>vector&lt;int&gt; ivec(ia, ia+7);<br><br>程式执行时会当掉。<br><br><br>我於是多做了一些观察，然後知道，上述这些动作根本上是完全<br>不对的。第一个 sample 之执行结果正确，完全是凑巧。<br><br>问题不在「最後一个元素是否符合删除条件」，而在对 iterator<br>特性的认识。当我们做了 ivec.erase(it) 动作，vector 便动态<br>减缩了一个元素（逻辑上，後继元素向前递补），而 it 不变。<br>之後 for 回圈的第三部份述句要求 it++，造成 it 跳过了一个元素...。<br><br>看实例：<br><br>(1) 初值为 {0,1,2,3,4,5,6}<br><br>第一次迭代，发现是偶数： ★ 以下以 e 表示 end()<br>0 1 2 3 4 5 6 e<br>^<br>第二次迭代，发现是奇数：<br>0 1 2 3 4 5 6 e<br>  ^<br>於是将  '1'  删除，vector 变成：<br>0 2 3 4 5 6 e<br>  ^<br>第三次迭代，发现是奇数（这时已发生错误，因为 '2' 被跳过，没有检查）：<br>0 2 3 4 5 6 e<br>    ^<br>於是将 '3' 删除，vector 变成：<br>0 2 4 5 6 e<br>    ^<br>第四次迭代，发现是奇数（这时已发生错误，因为 '4' 被跳过，没有检查）：<br>0 2 4 5 6 e<br>      ^<br>於是将 '5' 删除，vector 变成：<br>0 2 4 6 e<br>      ^<br>第五次迭代，发现 it == vec.end()，於是跳离回圈：<br>0 2 4 6 e<br>        ^<br>此时 vector 剩馀 0 2 4 6，阴错阳差地与正确结果吻合。<br><br><br>(2) 初值为 {0,2,4,6,0,4,7}<br><br>第一次迭代，发现是偶数： ★ 以下以 e 表示 end()<br>0 2 4 6 0 4 7 e<br>^<br>第二次迭代，发现是偶数：<br>0 2 4 6 0 4 7 e<br>  ^<br>第三次迭代，发现是偶数：<br>0 2 4 6 0 4 7 e<br>    ^<br>第四次迭代，发现是偶数：<br>0 2 4 6 0 4 7 e<br>      ^<br>第五次迭代，发现是偶数：<br>0 2 4 6 0 4 7 e<br>        ^<br>第六次迭代，发现是偶数：<br>0 2 4 6 0 4 7 e<br>          ^<br>第七次迭代，发现是奇数：<br>0 2 4 6 0 4 7 e<br>            ^<br>於是将 '7' 删除，vector 变成：<br>0 2 4 6 0 4 e<br>            ^<br>第八次迭代，it 越过了 end()，造成越界错误。回圈何时结束，未可知也：<br>0 2 4 6 0 4 e ? ? ? ? ? ?<br>              ^<br><br>我的结论：<br><br>iterator 只适用於在「不更动 container 布局」的条件下，<br>对 container 做巡访动作。否则，对 iterator 的取值行为，<br>直观下极易误用。<br><br>我记得《C++ Primer》中提过这个观念，但一下子找不出页数。<br><br><br>●应该怎麽做？<br><br>要解决上述问题（在 vector 中删除符合某条件的所有元素），<br>应该使用泛型演算法 remove_if() 再搭配 vector 的 erase()：<br><br>it = remove_if(ivec.begin(), ivec.end(), bind2nd(modulus&lt;int&gt;(), 2));<br>ivec.erase(it, ivec.end());<br><br><br>●list 的元素删除<br><br>面对 list，不可以直接对其 iterator 做算术运算，因为 list<br>的元素并不连续储存於记忆体中（《C++ Primer》p.266）。<br><br>那麽是不是应该延用泛型演算法 remove_if() 呢？不！<br>《C++ Primer》p.607 说：<br><br>-- quote ---<br>由於 list 不支持随机存取，merge(), remove(), reverse(), sort(),<br>和 unique() 等泛型演算法最好不要施行於 list objects 身上。<br>上述每一个演算法在 list 之中都有对应的成员函式可用：<br><br>* list::merge() 将两个排序过的 lists 合并在一起。<br>* list::remove() 将「与某数值相等」的元素移除掉。<br>* list::remove_if() 将「与某条件相符」的元素移除掉。<br>* list::reverse() 将 list 中的元素逆向排列。<br>* list::sort() 对 list 元素排序。<br>* list::splice() 将某个 list 的元素搬移到另一个 list 上。<br>* list::unique() 删除某一元素的连续副本。<br>-- unquote ---<br><br>所以，我们应该这麽做：<br><br>int ia[7] = {0,1,2,3,4,5,6};<br>list&lt;int&gt; ilist(ia, ia+7);<br>ilist.remove_if(bind2nd(modulus&lt;int&gt;(), 2));<br><img src ="http://www.cppblog.com/lucky_fox/aggbug/3676.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lucky_fox/" target="_blank">lucky_fox</a> 2006-03-03 12:09 <a href="http://www.cppblog.com/lucky_fox/archive/2006/03/03/3228.html#3676#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>re: 为什么Dev-C++可以编译执行，但是VC编译出错，为什么？？</title><link>http://www.cppblog.com/lucky_fox/archive/2005/12/22/1873.html#1984</link><dc:creator>lucky_fox</dc:creator><author>lucky_fox</author><pubDate>Thu, 22 Dec 2005 15:43:00 GMT</pubDate><guid>http://www.cppblog.com/lucky_fox/archive/2005/12/22/1873.html#1984</guid><description><![CDATA[谢谢paracelsus，打了sp6之后，问题确实解决了！<img src ="http://www.cppblog.com/lucky_fox/aggbug/1984.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lucky_fox/" target="_blank">lucky_fox</a> 2005-12-22 23:43 <a href="http://www.cppblog.com/lucky_fox/archive/2005/12/22/1873.html#1984#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>re: 为什么Dev-C++可以编译执行，但是VC编译出错，为什么？？</title><link>http://www.cppblog.com/lucky_fox/archive/2005/12/22/1873.html#1968</link><dc:creator>paracelsus</dc:creator><author>paracelsus</author><pubDate>Thu, 22 Dec 2005 10:35:00 GMT</pubDate><guid>http://www.cppblog.com/lucky_fox/archive/2005/12/22/1873.html#1968</guid><description><![CDATA[你的VC6.0没有打SP6<img src ="http://www.cppblog.com/lucky_fox/aggbug/1968.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lucky_fox/" target="_blank">paracelsus</a> 2005-12-22 18:35 <a href="http://www.cppblog.com/lucky_fox/archive/2005/12/22/1873.html#1968#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>re: 为什么Dev-C++可以编译执行，但是VC编译出错，为什么？？</title><link>http://www.cppblog.com/lucky_fox/archive/2005/12/19/1873.html#1883</link><dc:creator>lucky_fox</dc:creator><author>lucky_fox</author><pubDate>Mon, 19 Dec 2005 07:49:00 GMT</pubDate><guid>http://www.cppblog.com/lucky_fox/archive/2005/12/19/1873.html#1883</guid><description><![CDATA[好像是不支持友元重载操作符，当我把重载操作符＋的声明和实现屏蔽掉之后，在VC中可以正确编译和执行！奇怪！！！！why？？？？<img src ="http://www.cppblog.com/lucky_fox/aggbug/1883.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lucky_fox/" target="_blank">lucky_fox</a> 2005-12-19 15:49 <a href="http://www.cppblog.com/lucky_fox/archive/2005/12/19/1873.html#1883#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>